├── .github └── PULL_REQUEST_TEMPLATE │ └── pull_request_template.md ├── .gitignore ├── .idea ├── codeStyleSettings.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml ├── statistic.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── jacoco.gradle ├── proguard-rules.pro ├── schemas │ ├── com.cn29.aac.datasource.GithubDb │ │ └── 3.json │ ├── com.cn29.aac.datasource.auth.AuthDb │ │ └── 1.json │ ├── com.cn29.aac.datasource.auth.db.AuthDb │ │ └── 1.json │ ├── com.cn29.aac.datasource.feedentry.db.AppDatabase │ │ ├── 1.json │ │ ├── 2.json │ │ └── 3.json │ ├── com.cn29.aac.datasource.github.GithubDb │ │ └── 3.json │ ├── com.cn29.aac.datasource.github.db.GithubDb │ │ └── 3.json │ ├── com.cn29.aac.datasource.itunes.db.ItunesDb │ │ └── 3.json │ ├── com.cn29.aac.datasource.room.AppDatabase │ │ └── 3.json │ ├── sampleproj.charlesng0209.com.sampleapparch.architecture.datasource.room.AppDatabase │ │ └── 3.json │ └── sampleproj.charlesng0209.com.sampleapparch.architecture.room.AppDatabase │ │ └── 3.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── cn29 │ │ └── aac │ │ ├── ExampleInstrumentedTest.java │ │ ├── datasource │ │ ├── auth │ │ │ └── db │ │ │ │ └── AuthDaoTest.kt │ │ ├── feedentry │ │ │ └── db │ │ │ │ ├── FeedEntryDAOTest.kt │ │ │ │ └── migration │ │ │ │ └── MigrationTest.kt │ │ ├── github │ │ │ └── db │ │ │ │ ├── RepoDaoTest.kt │ │ │ │ └── UserDaoTest.kt │ │ └── itunes │ │ │ └── db │ │ │ ├── AlbumDaoTest.kt │ │ │ └── ArtistDaoTest.kt │ │ ├── ui │ │ └── feedentry │ │ │ └── FeedActivityTest.kt │ │ └── utils │ │ └── LiveDataTestUtil.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── cn29 │ │ │ └── aac │ │ │ ├── AppExecutors.kt │ │ │ ├── MyApplication.kt │ │ │ ├── binding │ │ │ ├── Converter.kt │ │ │ ├── CustomConverter.kt │ │ │ ├── EditTextBindingUtil.kt │ │ │ ├── ImageBindingUtil.kt │ │ │ ├── SpinnerBindingUtil.kt │ │ │ ├── TextInputEditTextBindingUtil.kt │ │ │ └── TextViewBindingUtil.kt │ │ │ ├── datasource │ │ │ ├── api │ │ │ │ ├── ApiResponse.kt │ │ │ │ ├── LiveDataCallAdapter.kt │ │ │ │ └── LiveDataCallAdapterFactory.kt │ │ │ ├── auth │ │ │ │ ├── db │ │ │ │ │ ├── AuthDao.kt │ │ │ │ │ └── AuthDb.kt │ │ │ │ └── remote │ │ │ │ │ ├── FacebookAuth.kt │ │ │ │ │ ├── GoogleAuth.kt │ │ │ │ │ └── MyCompanyAuth.kt │ │ │ ├── feedentry │ │ │ │ └── db │ │ │ │ │ ├── AppDatabase.kt │ │ │ │ │ ├── FeedEntryDAO.kt │ │ │ │ │ └── migration │ │ │ │ │ ├── Migration1_2.kt │ │ │ │ │ └── Migration2_3.kt │ │ │ ├── github │ │ │ │ ├── db │ │ │ │ │ ├── GithubDb.kt │ │ │ │ │ ├── RepoDao.kt │ │ │ │ │ └── UserDao.kt │ │ │ │ └── remote │ │ │ │ │ ├── GithubService.kt │ │ │ │ │ ├── GithubTypeConverters.kt │ │ │ │ │ └── RepoSearchResponse.kt │ │ │ ├── itunes │ │ │ │ ├── db │ │ │ │ │ ├── AlbumDao.kt │ │ │ │ │ ├── ArtistDao.kt │ │ │ │ │ └── ItunesDb.kt │ │ │ │ └── remote │ │ │ │ │ └── ItunesService.kt │ │ │ ├── order │ │ │ │ └── db │ │ │ │ │ ├── OrderDao.kt │ │ │ │ │ └── OrderDb.kt │ │ │ └── shoppingkart │ │ │ │ └── db │ │ │ │ ├── KartDao.kt │ │ │ │ └── KartDb.kt │ │ │ ├── di │ │ │ ├── AppComponent.kt │ │ │ ├── AppModule.kt │ │ │ ├── datasources │ │ │ │ ├── db │ │ │ │ │ └── RoomModule.kt │ │ │ │ └── remote │ │ │ │ │ ├── AuthModule.kt │ │ │ │ │ └── RESTModule.kt │ │ │ ├── repo │ │ │ │ └── RepoModule.kt │ │ │ ├── scope │ │ │ │ ├── AndroidDataBinding.kt │ │ │ │ └── ViewModel.kt │ │ │ └── ui │ │ │ │ └── UiBuilder.kt │ │ │ ├── repo │ │ │ ├── feedentry │ │ │ │ ├── FeedEntry.kt │ │ │ │ └── FeedEntryRepository.kt │ │ │ ├── github │ │ │ │ ├── Contributor.kt │ │ │ │ ├── GitRepoRepository.java │ │ │ │ ├── Repo.kt │ │ │ │ ├── RepoSearchResult.kt │ │ │ │ └── User.kt │ │ │ ├── itunes │ │ │ │ ├── Album.kt │ │ │ │ ├── AlbumSearchResult.kt │ │ │ │ ├── Artist.kt │ │ │ │ ├── ArtistSearchResult.kt │ │ │ │ └── ItunesRepository.java │ │ │ ├── location │ │ │ │ └── LastLocationListener.kt │ │ │ ├── shoppingkart │ │ │ │ ├── Kart.kt │ │ │ │ └── KartRepository.kt │ │ │ ├── user │ │ │ │ ├── AuthRepository.java │ │ │ │ └── LoginBean.kt │ │ │ └── util │ │ │ │ ├── GenericNetworkBoundResource.java │ │ │ │ ├── GenericNetworkBoundResourceBuilder.java │ │ │ │ ├── NetworkBoundResource.java │ │ │ │ ├── RateLimiter.kt │ │ │ │ ├── Resource.kt │ │ │ │ ├── Status.kt │ │ │ │ └── TypeConvertor.kt │ │ │ └── ui │ │ │ ├── base │ │ │ ├── BaseAppCompatActivity.kt │ │ │ └── BaseFragment.kt │ │ │ ├── common │ │ │ ├── ActivityPermissionComponent.kt │ │ │ ├── ActivityPermissionComponentBuilder.kt │ │ │ ├── AlertDialogComponent.kt │ │ │ ├── BaseRecyclerViewAdapter.kt │ │ │ ├── FragmentPermissionComponent.kt │ │ │ ├── PermissionComponentBuilder.kt │ │ │ └── ProgressDialogComponent.kt │ │ │ ├── feedentry │ │ │ ├── FeedActivity.kt │ │ │ ├── FeedActivityModule.kt │ │ │ ├── FeedEntryAdapter.kt │ │ │ ├── FeedEntryFragment.kt │ │ │ ├── FeedEntryFragmentModule.kt │ │ │ └── vm │ │ │ │ ├── FeedEntryListViewModel.kt │ │ │ │ └── FeedEntryListViewModelFactory.kt │ │ │ ├── feedentrydetail │ │ │ ├── FeedEntryDetailActivity.kt │ │ │ ├── FeedEntryDetailActivityModule.kt │ │ │ └── vm │ │ │ │ ├── FeedEntryDetailViewModel.kt │ │ │ │ └── FeedEntryDetailViewModelFactory.kt │ │ │ ├── location │ │ │ ├── LocationActivity.kt │ │ │ ├── LocationActivityModule.kt │ │ │ ├── LocationFragment.kt │ │ │ ├── LocationFragmentModule.kt │ │ │ └── vm │ │ │ │ ├── LastLocationViewModel.kt │ │ │ │ └── LastLocationViewModelFactory.kt │ │ │ ├── login │ │ │ ├── LoginActivity.kt │ │ │ ├── LoginActivityModule.kt │ │ │ └── vm │ │ │ │ ├── LoginViewModel.kt │ │ │ │ └── LoginViewModelFactory.kt │ │ │ ├── main │ │ │ ├── AppArchNavigationDrawer.kt │ │ │ ├── AppArchNavigationDrawerModule.kt │ │ │ └── vm │ │ │ │ ├── AppArchNavViewModel.kt │ │ │ │ └── AppArchNavViewModelFactory.kt │ │ │ ├── masterdetail │ │ │ ├── GithubRepoAdapter.kt │ │ │ ├── SimpleDetailActivity.kt │ │ │ ├── SimpleDetailActivityModule.kt │ │ │ ├── SimpleDetailFragment.kt │ │ │ ├── SimpleDetailFragmentModule.kt │ │ │ ├── SimpleListActivity.kt │ │ │ ├── SimpleListActivityModule.kt │ │ │ └── vm │ │ │ │ ├── SimpleMasterDetailShareViewModel.kt │ │ │ │ └── SimpleMasterDetailShareViewModelFactory.kt │ │ │ ├── setting │ │ │ ├── AppCompatPreferenceActivity.kt │ │ │ ├── SettingsActivity.kt │ │ │ ├── SettingsActivityModule.kt │ │ │ └── vm │ │ │ │ ├── SettingsActivityViewModel.kt │ │ │ │ └── SettingsActivityViewModelFactory.kt │ │ │ ├── shopping │ │ │ ├── AlbumAdapter.kt │ │ │ ├── AlbumFragment.kt │ │ │ ├── AlbumFragmentModule.kt │ │ │ ├── ArtistAdapter.kt │ │ │ ├── ArtistDetailActivity.kt │ │ │ ├── ArtistDetailActivityModule.kt │ │ │ ├── ArtistFragment.kt │ │ │ ├── ArtistFragmentModule.kt │ │ │ ├── ArtistsSearchRecentSuggestionsProvider.kt │ │ │ ├── ShoppingActivity.kt │ │ │ ├── ShoppingActivityModule.kt │ │ │ └── vm │ │ │ │ ├── AlbumFragmentViewModel.kt │ │ │ │ ├── AlbumFragmentViewModelFactory.kt │ │ │ │ ├── ArtistDetailActivityViewModel.kt │ │ │ │ ├── ArtistDetailActivityViewModelFactory.kt │ │ │ │ ├── ArtistFragmentViewModel.kt │ │ │ │ ├── ArtistFragmentViewModelFactory.kt │ │ │ │ ├── ShoppingActivityViewModel.kt │ │ │ │ └── ShoppingActivityViewModelFactory.kt │ │ │ ├── shoppingkart │ │ │ ├── ShoppingKartActivity.kt │ │ │ ├── ShoppingKartActivityModule.kt │ │ │ └── vm │ │ │ │ ├── ShoppingKartActivityViewModel.kt │ │ │ │ └── ShoppingKartActivityViewModelFactory.kt │ │ │ └── viewpager │ │ │ ├── BlankFragmentA.kt │ │ │ ├── BlankFragmentAModule.kt │ │ │ ├── BlankFragmentB.kt │ │ │ ├── BlankFragmentBModule.kt │ │ │ ├── PagerActivity.kt │ │ │ ├── PagerActivityModule.kt │ │ │ └── vm │ │ │ └── PagerAgentViewModel.kt │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_add_shopping_cart_black_24dp.png │ │ ├── ic_add_shopping_cart_white_24dp.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_album_black_24dp.png │ │ ├── ic_delete_black_24dp.png │ │ ├── ic_exit_to_app_black_24dp.png │ │ ├── ic_exit_to_app_grey_700_24dp.png │ │ ├── ic_favorite_black_24dp.png │ │ ├── ic_history_black_24dp.png │ │ ├── ic_mode_edit_black_24dp.png │ │ ├── ic_people_black_24dp.png │ │ ├── ic_refresh_white_24dp.png │ │ ├── ic_reorder_black_24dp.png │ │ ├── ic_search_black_24dp.png │ │ ├── ic_search_white_24dp.png │ │ ├── ic_settings_black_24dp.png │ │ ├── ic_share_black_24dp.png │ │ ├── ic_shopping_cart_black_24dp.png │ │ └── ic_star_black_24dp.png │ │ ├── drawable-mdpi │ │ ├── ic_add_shopping_cart_black_24dp.png │ │ ├── ic_add_shopping_cart_white_24dp.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_album_black_24dp.png │ │ ├── ic_delete_black_24dp.png │ │ ├── ic_exit_to_app_black_24dp.png │ │ ├── ic_exit_to_app_grey_700_24dp.png │ │ ├── ic_favorite_black_24dp.png │ │ ├── ic_history_black_24dp.png │ │ ├── ic_mode_edit_black_24dp.png │ │ ├── ic_people_black_24dp.png │ │ ├── ic_refresh_white_24dp.png │ │ ├── ic_reorder_black_24dp.png │ │ ├── ic_search_black_24dp.png │ │ ├── ic_search_white_24dp.png │ │ ├── ic_settings_black_24dp.png │ │ ├── ic_share_black_24dp.png │ │ ├── ic_shopping_cart_black_24dp.png │ │ └── ic_star_black_24dp.png │ │ ├── drawable-v21 │ │ ├── ic_menu_camera.xml │ │ ├── ic_menu_gallery.xml │ │ ├── ic_menu_manage.xml │ │ ├── ic_menu_send.xml │ │ ├── ic_menu_share.xml │ │ └── ic_menu_slideshow.xml │ │ ├── drawable-xhdpi │ │ ├── ic_add_shopping_cart_black_24dp.png │ │ ├── ic_add_shopping_cart_white_24dp.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_album_black_24dp.png │ │ ├── ic_delete_black_24dp.png │ │ ├── ic_exit_to_app_black_24dp.png │ │ ├── ic_exit_to_app_grey_700_24dp.png │ │ ├── ic_favorite_black_24dp.png │ │ ├── ic_history_black_24dp.png │ │ ├── ic_mode_edit_black_24dp.png │ │ ├── ic_people_black_24dp.png │ │ ├── ic_refresh_white_24dp.png │ │ ├── ic_reorder_black_24dp.png │ │ ├── ic_search_black_24dp.png │ │ ├── ic_search_white_24dp.png │ │ ├── ic_settings_black_24dp.png │ │ ├── ic_share_black_24dp.png │ │ ├── ic_shopping_cart_black_24dp.png │ │ └── ic_star_black_24dp.png │ │ ├── drawable-xxhdpi │ │ ├── ic_add_shopping_cart_black_24dp.png │ │ ├── ic_add_shopping_cart_white_24dp.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_album_black_24dp.png │ │ ├── ic_delete_black_24dp.png │ │ ├── ic_exit_to_app_black_24dp.png │ │ ├── ic_exit_to_app_grey_700_24dp.png │ │ ├── ic_favorite_black_24dp.png │ │ ├── ic_history_black_24dp.png │ │ ├── ic_mode_edit_black_24dp.png │ │ ├── ic_people_black_24dp.png │ │ ├── ic_refresh_white_24dp.png │ │ ├── ic_reorder_black_24dp.png │ │ ├── ic_search_black_24dp.png │ │ ├── ic_search_white_24dp.png │ │ ├── ic_settings_black_24dp.png │ │ ├── ic_share_black_24dp.png │ │ ├── ic_shopping_cart_black_24dp.png │ │ └── ic_star_black_24dp.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_add_shopping_cart_black_24dp.png │ │ ├── ic_add_shopping_cart_white_24dp.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_album_black_24dp.png │ │ ├── ic_delete_black_24dp.png │ │ ├── ic_exit_to_app_black_24dp.png │ │ ├── ic_exit_to_app_grey_700_24dp.png │ │ ├── ic_favorite_black_24dp.png │ │ ├── ic_history_black_24dp.png │ │ ├── ic_mode_edit_black_24dp.png │ │ ├── ic_people_black_24dp.png │ │ ├── ic_refresh_white_24dp.png │ │ ├── ic_reorder_black_24dp.png │ │ ├── ic_search_black_24dp.png │ │ ├── ic_search_white_24dp.png │ │ ├── ic_settings_black_24dp.png │ │ ├── ic_share_black_24dp.png │ │ ├── ic_shopping_cart_black_24dp.png │ │ └── ic_star_black_24dp.png │ │ ├── drawable │ │ ├── ic_dashboard_black_24dp.xml │ │ ├── ic_home_black_24dp.xml │ │ ├── ic_info_black_24dp.xml │ │ ├── ic_notifications_black_24dp.xml │ │ ├── ic_sync_black_24dp.xml │ │ └── side_nav_bar.xml │ │ ├── layout-w900dp │ │ └── fragment_simple_list.xml │ │ ├── layout │ │ ├── activity_app_arch_navigation_drawer.xml │ │ ├── activity_artist_detail.xml │ │ ├── activity_feed.xml │ │ ├── activity_feed_entry_detail.xml │ │ ├── activity_location.xml │ │ ├── activity_login.xml │ │ ├── activity_pager.xml │ │ ├── activity_shopping.xml │ │ ├── activity_shopping_kart.xml │ │ ├── activity_simple_detail.xml │ │ ├── activity_simple_list.xml │ │ ├── app_bar_app_arch_navigation_drawer.xml │ │ ├── content_app_arch_navigation_drawer.xml │ │ ├── content_artist_detail.xml │ │ ├── content_location.xml │ │ ├── content_pager.xml │ │ ├── content_shopping_kart.xml │ │ ├── dialog_feedentry.xml │ │ ├── fragment_album.xml │ │ ├── fragment_artist.xml │ │ ├── fragment_blank_a.xml │ │ ├── fragment_blank_b.xml │ │ ├── fragment_feedentry_list.xml │ │ ├── fragment_location.xml │ │ ├── fragment_simple_detail.xml │ │ ├── fragment_simple_list.xml │ │ ├── fragment_simple_list_content.xml │ │ ├── item_album_card.xml │ │ ├── item_album_list.xml │ │ ├── item_artist_card.xml │ │ ├── item_artist_grid.xml │ │ ├── item_feedentry_card.xml │ │ ├── item_github_card.xml │ │ ├── nav_header_app_arch_navigation_drawer.xml │ │ └── progress_dialog.xml │ │ ├── menu │ │ ├── activity_app_arch_navigation_drawer_drawer.xml │ │ ├── app_arch_navigation_drawer.xml │ │ ├── menu_artist_card.xml │ │ ├── menu_artist_detail.xml │ │ ├── menu_feed.xml │ │ ├── menu_feed_entry_detail.xml │ │ ├── menu_feed_item_card.xml │ │ ├── navigation.xml │ │ └── options_menu.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── pref_data_sync.xml │ │ ├── pref_general.xml │ │ ├── pref_headers.xml │ │ ├── pref_notification.xml │ │ └── searchable.xml │ └── test │ ├── java │ └── com │ │ └── cn29 │ │ └── aac │ │ ├── datasource │ │ ├── api │ │ │ ├── ApiResponseTest.kt │ │ │ ├── LiveDataCallAdapterFactoryTest.kt │ │ │ ├── LiveDataCallAdapterTest.kt │ │ │ └── MockItunesService.kt │ │ ├── auth │ │ │ └── remote │ │ │ │ ├── FacebookAuthTest.kt │ │ │ │ ├── GoogleAuthTest.kt │ │ │ │ └── MyCompanyAuthTest.kt │ │ └── github │ │ │ └── remote │ │ │ └── GithubTypeConvertersTest.kt │ │ └── utils │ │ └── InstantExecutorExtension.kt │ └── resources │ ├── abc.txt │ └── data │ ├── github │ └── users │ │ └── googlesamples │ │ └── repos │ │ └── get_200.json │ └── itunes │ ├── lookup │ └── get_200.json │ └── search │ └── get_200.json ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── init.sh ├── markdown ├── feedentry.md ├── feedentrydetail.md ├── img │ ├── feed_entry_1.png │ ├── feed_entry_2.png │ ├── feed_entry_3.png │ ├── feed_entry_4.png │ ├── fragment_communication_1.png │ ├── fragment_communication_2.png │ ├── fragment_communication_3.png │ ├── location_1.png │ ├── master_detail_1.png │ ├── master_detail_2.png │ ├── master_detail_3.png │ ├── view_pager_1.png │ └── view_pager_2.png ├── itunes_api.md ├── location.md ├── masterdetail.md └── viewpager.md ├── prepare-commit-msg.sample ├── settings.gradle └── style └── intellij-java-google-style.xml /.github/PULL_REQUEST_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. 4 | 5 | Fixes # (issue) 6 | 7 | ## Type of change 8 | 9 | Please delete options that are not relevant. 10 | 11 | - [ ] Bug fix (non-breaking change which fixes an issue) 12 | - [ ] New feature (non-breaking change which adds functionality) 13 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 14 | - [ ] This change requires a documentation update 15 | 16 | # How Has This Been Tested? 17 | 18 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration 19 | 20 | - [ ] Test A 21 | - [ ] Test B 22 | 23 | **Test Configuration**: 24 | * Firmware version: 25 | * Hardware: 26 | * Toolchain: 27 | * SDK: 28 | 29 | # Checklist: 30 | 31 | - [ ] My code follows the style guidelines of this project 32 | - [ ] I have performed a self-review of my own code 33 | - [ ] I have commented my code, particularly in hard-to-understand areas 34 | - [ ] I have made corresponding changes to the documentation 35 | - [ ] My changes generate no new warnings 36 | - [ ] I have added tests that prove my fix is effective or that my feature works 37 | - [ ] New and existing unit tests pass locally with my changes 38 | - [ ] Any dependent changes have been merged and published in downstream modules -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | # Uncomment the following line in case you need and you don't have the release build type files in your app 18 | # release/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # IntelliJ 40 | *.iml 41 | .idea/** 42 | .idea/workspace.xml 43 | .idea/tasks.xml 44 | .idea/gradle.xml 45 | .idea/assetWizardSettings.xml 46 | .idea/dictionaries 47 | .idea/libraries 48 | # Android Studio 3 in .gitignore file. 49 | .idea/caches 50 | .idea/modules.xml 51 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 52 | .idea/navEditor.xml 53 | 54 | # Keystore files 55 | # Uncomment the following lines if you do not want to check your keystore files in. 56 | #*.jks 57 | #*.keystore 58 | 59 | # External native build folder generated in Android Studio 2.2 and later 60 | .externalNativeBuild 61 | .cxx/ 62 | 63 | # Google Services (e.g. APIs or Firebase) 64 | app/google-services.json 65 | 66 | # Freeline 67 | freeline.py 68 | freeline/ 69 | freeline_project_description.json 70 | 71 | # fastlane 72 | fastlane/report.xml 73 | fastlane/Preview.html 74 | fastlane/screenshots 75 | fastlane/test_output 76 | fastlane/readme.md 77 | 78 | # Version control 79 | vcs.xml 80 | 81 | # lint 82 | lint/intermediates/ 83 | lint/generated/ 84 | lint/outputs/ 85 | lint/tmp/ 86 | # lint/reports/ -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/statistic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/charlesng0209/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/schemas/com.cn29.aac.datasource.auth.AuthDb/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 1, 5 | "identityHash": "a34cf41b8e934746d339d638b8aee8c0", 6 | "entities": [ 7 | { 8 | "tableName": "Auth", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `authType` TEXT, `isLogin` INTEGER NOT NULL, PRIMARY KEY(`email`))", 10 | "fields": [ 11 | { 12 | "fieldPath": "email", 13 | "columnName": "email", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "authType", 19 | "columnName": "authType", 20 | "affinity": "TEXT", 21 | "notNull": false 22 | }, 23 | { 24 | "fieldPath": "isLogin", 25 | "columnName": "isLogin", 26 | "affinity": "INTEGER", 27 | "notNull": true 28 | } 29 | ], 30 | "primaryKey": { 31 | "columnNames": [ 32 | "email" 33 | ], 34 | "autoGenerate": false 35 | }, 36 | "indices": [], 37 | "foreignKeys": [] 38 | } 39 | ], 40 | "setupQueries": [ 41 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 42 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"a34cf41b8e934746d339d638b8aee8c0\")" 43 | ] 44 | } 45 | } -------------------------------------------------------------------------------- /app/schemas/com.cn29.aac.datasource.auth.db.AuthDb/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 1, 5 | "identityHash": "8c016dd61a397dae2c8860d4b7aecb34", 6 | "entities": [ 7 | { 8 | "tableName": "Auth", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `authType` TEXT NOT NULL, `isLogin` INTEGER NOT NULL, `password` TEXT, PRIMARY KEY(`email`))", 10 | "fields": [ 11 | { 12 | "fieldPath": "email", 13 | "columnName": "email", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "authType", 19 | "columnName": "authType", 20 | "affinity": "TEXT", 21 | "notNull": true 22 | }, 23 | { 24 | "fieldPath": "isLogin", 25 | "columnName": "isLogin", 26 | "affinity": "INTEGER", 27 | "notNull": true 28 | }, 29 | { 30 | "fieldPath": "password", 31 | "columnName": "password", 32 | "affinity": "TEXT", 33 | "notNull": false 34 | } 35 | ], 36 | "primaryKey": { 37 | "columnNames": [ 38 | "email" 39 | ], 40 | "autoGenerate": false 41 | }, 42 | "indices": [], 43 | "foreignKeys": [] 44 | } 45 | ], 46 | "views": [], 47 | "setupQueries": [ 48 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 49 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8c016dd61a397dae2c8860d4b7aecb34')" 50 | ] 51 | } 52 | } -------------------------------------------------------------------------------- /app/schemas/com.cn29.aac.datasource.feedentry.db.AppDatabase/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 1, 5 | "identityHash": "52d4257970e7ba2b69d0e4f468aad738", 6 | "entities": [ 7 | { 8 | "tableName": "feedEntrys", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`title` TEXT NOT NULL, `subtitle` TEXT NOT NULL, `uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", 10 | "fields": [ 11 | { 12 | "fieldPath": "title", 13 | "columnName": "title", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "subTitle", 19 | "columnName": "subtitle", 20 | "affinity": "TEXT", 21 | "notNull": true 22 | }, 23 | { 24 | "fieldPath": "uid", 25 | "columnName": "uid", 26 | "affinity": "INTEGER", 27 | "notNull": true 28 | } 29 | ], 30 | "primaryKey": { 31 | "columnNames": [ 32 | "uid" 33 | ], 34 | "autoGenerate": true 35 | }, 36 | "indices": [], 37 | "foreignKeys": [] 38 | } 39 | ], 40 | "views": [], 41 | "setupQueries": [ 42 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 43 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '52d4257970e7ba2b69d0e4f468aad738')" 44 | ] 45 | } 46 | } -------------------------------------------------------------------------------- /app/schemas/com.cn29.aac.datasource.feedentry.db.AppDatabase/2.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 2, 5 | "identityHash": "52d4257970e7ba2b69d0e4f468aad738", 6 | "entities": [ 7 | { 8 | "tableName": "feedEntrys", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`title` TEXT NOT NULL, `subtitle` TEXT NOT NULL, `imageUrl` TEXT, `uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", 10 | "fields": [ 11 | { 12 | "fieldPath": "title", 13 | "columnName": "title", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "subTitle", 19 | "columnName": "subtitle", 20 | "affinity": "TEXT", 21 | "notNull": true 22 | }, 23 | { 24 | "fieldPath": "imageUrl", 25 | "columnName": "imageUrl", 26 | "affinity": "TEXT", 27 | "notNull": false 28 | }, 29 | { 30 | "fieldPath": "uid", 31 | "columnName": "uid", 32 | "affinity": "INTEGER", 33 | "notNull": true 34 | } 35 | ], 36 | "primaryKey": { 37 | "columnNames": [ 38 | "uid" 39 | ], 40 | "autoGenerate": true 41 | }, 42 | "indices": [], 43 | "foreignKeys": [] 44 | } 45 | ], 46 | "views": [], 47 | "setupQueries": [ 48 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 49 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '52d4257970e7ba2b69d0e4f468aad738')" 50 | ] 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/cn29/aac/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.cn29.aac; 2 | 3 | import android.content.Context; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | 8 | import androidx.test.platform.app.InstrumentationRegistry; 9 | import androidx.test.runner.AndroidJUnit4; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | 20 | @Test 21 | public void useAppContext() throws Exception { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getContext(); 24 | assertEquals("com.cn29.aac.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/cn29/aac/ui/feedentry/FeedActivityTest.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.feedentry 2 | 3 | 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | import androidx.test.filters.LargeTest 6 | import androidx.test.rule.ActivityTestRule 7 | import org.junit.Rule 8 | import org.junit.Test 9 | import org.junit.runner.RunWith 10 | 11 | @RunWith(AndroidJUnit4::class) 12 | @LargeTest 13 | class FeedActivityTest { 14 | 15 | @get:Rule 16 | var activityRule: ActivityTestRule = ActivityTestRule( 17 | FeedActivity::class.java) 18 | 19 | @Test 20 | fun should_open_feed_page() { 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/cn29/aac/utils/LiveDataTestUtil.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.utils 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.Observer 5 | import java.util.concurrent.CountDownLatch 6 | import java.util.concurrent.TimeUnit 7 | 8 | object LiveDataTestUtil { 9 | // @Throws(InterruptedException::class) 10 | fun getValue(liveData: LiveData): T { 11 | val data = arrayOfNulls(1) 12 | val latch = CountDownLatch(1) 13 | val observer = object : Observer { 14 | override fun onChanged(o: T?) { 15 | data[0] = o 16 | latch.countDown() 17 | liveData.removeObserver(this) 18 | } 19 | } 20 | liveData.observeForever(observer) 21 | latch.await(2, TimeUnit.SECONDS) 22 | 23 | return data[0] as T 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/AppExecutors.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import java.util.concurrent.Executor 6 | import java.util.concurrent.Executors 7 | import javax.inject.Inject 8 | import javax.inject.Singleton 9 | 10 | /** 11 | * Global executor pools for the whole application. 12 | * 13 | * 14 | * Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind 15 | * webservice requests). 16 | */ 17 | @Singleton 18 | class AppExecutors(private val diskIO: Executor, 19 | private val networkIO: Executor, 20 | private val mainThread: Executor) { 21 | 22 | @Inject 23 | constructor() : this(Executors.newSingleThreadExecutor(), 24 | Executors.newFixedThreadPool(3), 25 | MainThreadExecutor()) { 26 | } 27 | 28 | fun diskIO(): Executor { 29 | return diskIO 30 | } 31 | 32 | fun networkIO(): Executor { 33 | return networkIO 34 | } 35 | 36 | fun mainThread(): Executor { 37 | return mainThread 38 | } 39 | 40 | private class MainThreadExecutor : 41 | Executor { 42 | private val mainThreadHandler = Handler( 43 | Looper.getMainLooper()) 44 | 45 | override fun execute(command: Runnable) { 46 | mainThreadHandler.post(command) 47 | } 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/MyApplication.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac 2 | 3 | import android.app.Activity 4 | import android.app.Application 5 | import com.cn29.aac.di.DaggerAppComponent 6 | import com.facebook.stetho.Stetho 7 | import dagger.android.AndroidInjector 8 | import dagger.android.DispatchingAndroidInjector 9 | import dagger.android.HasActivityInjector 10 | import javax.inject.Inject 11 | 12 | /** 13 | * Created by Charles Ng on 7/9/2017. 14 | */ 15 | class MyApplication : Application(), 16 | HasActivityInjector { 17 | @JvmField 18 | @Inject 19 | var activityDispatchingAndroidInjector: DispatchingAndroidInjector? = null 20 | override fun onCreate() { 21 | super.onCreate() 22 | Stetho.initializeWithDefaults(this) 23 | DaggerAppComponent.builder().application(this).build().inject(this) 24 | } 25 | 26 | override fun activityInjector(): AndroidInjector { 27 | return activityDispatchingAndroidInjector!! 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/binding/Converter.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.binding 2 | 3 | import androidx.databinding.InverseMethod 4 | 5 | /** 6 | * Created by Charles Ng on 8/9/2017. From @George Mount answer https://stackoverflow.com/questions/44769054/android-two-way-databinding-for-methods-with-parameters/44782542#44782542 7 | * The inverse method can also be in class scope , not only in static scope 8 | * ***Can be extended 9 | */ 10 | open class Converter protected constructor() { 11 | @InverseMethod("fromDouble") 12 | fun toDouble(text: String?): Double { 13 | return java.lang.Double.valueOf(text!!) 14 | } 15 | 16 | fun fromDouble(value: Double): String { 17 | return value.toString() 18 | } 19 | 20 | @InverseMethod("fromInteger") 21 | fun toInteger(text: String?): Int { 22 | return Integer.valueOf(text!!) 23 | } 24 | 25 | fun fromInteger(value: Int): String { 26 | return value.toString() 27 | } 28 | 29 | companion object { 30 | private var converter: Converter? = null 31 | val default: Converter? 32 | get() { 33 | if (converter == null) { 34 | converter = Converter() 35 | } 36 | return converter 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/binding/CustomConverter.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.binding 2 | 3 | /** 4 | * Created by Charles Ng on 8/9/2017. 5 | */ 6 | class CustomConverter : Converter() -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/binding/EditTextBindingUtil.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.binding 2 | 3 | import android.widget.EditText 4 | import androidx.databinding.InverseMethod 5 | 6 | /** 7 | * Created by Charles Ng on 7/9/2017. 8 | */ 9 | class EditTextBindingUtil { 10 | @InverseMethod("inverseText") 11 | fun bindText(editText: EditText, 12 | newValue: String): String { 13 | editText.setText(newValue) 14 | return newValue 15 | } 16 | 17 | fun inverseText(editText: EditText): String { 18 | return editText.text.toString() 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/binding/ImageBindingUtil.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.binding 2 | 3 | import android.widget.ImageView 4 | import androidx.databinding.BindingAdapter 5 | import com.squareup.picasso.Picasso 6 | import de.hdodenhof.circleimageview.CircleImageView 7 | 8 | /** 9 | * Created by charlesng0209 on 10/9/2017. 10 | */ 11 | object ImageBindingUtil { 12 | @JvmStatic 13 | @BindingAdapter("imageUrl") 14 | fun loadImage(view: ImageView, 15 | url: String?) { 16 | Picasso.with(view.context).load(url).into(view) 17 | } 18 | 19 | @BindingAdapter("imageUrl") 20 | fun loadCircleImage(view: CircleImageView, 21 | url: String?) { 22 | Picasso.with(view.context).load(url).into(view) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/binding/TextViewBindingUtil.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.binding 2 | 3 | /** 4 | * Created by Charles Ng on 7/9/2017. 5 | */ 6 | class TextViewBindingUtil -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/api/LiveDataCallAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.api 2 | 3 | import androidx.lifecycle.LiveData 4 | import retrofit2.Call 5 | import retrofit2.CallAdapter 6 | import retrofit2.Callback 7 | import retrofit2.Response 8 | import java.lang.reflect.Type 9 | import java.util.concurrent.atomic.AtomicBoolean 10 | 11 | class LiveDataCallAdapter(private val responseType: Type) : CallAdapter>> { 12 | override fun responseType(): Type { 13 | return responseType 14 | } 15 | 16 | override fun adapt(call: Call): LiveData> { 17 | return object : LiveData>() { 18 | var started = AtomicBoolean(false) 19 | override fun onActive() { 20 | super.onActive() 21 | if (started.compareAndSet(false, true)) { 22 | call.enqueue(object : Callback { 23 | override fun onResponse(call: Call, response: Response) { 24 | postValue(ApiResponse(response)) 25 | } 26 | 27 | override fun onFailure(call: Call, throwable: Throwable) { 28 | postValue(ApiResponse(throwable)) 29 | } 30 | }) 31 | } 32 | } 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/api/LiveDataCallAdapterFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.api 2 | 3 | import androidx.lifecycle.LiveData 4 | import com.cn29.aac.datasource.api.ApiResponse 5 | import retrofit2.CallAdapter 6 | import retrofit2.Retrofit 7 | import java.lang.reflect.ParameterizedType 8 | import java.lang.reflect.Type 9 | 10 | class LiveDataCallAdapterFactory : CallAdapter.Factory() { 11 | override fun get(returnType: Type, annotations: Array, retrofit: Retrofit): CallAdapter<*, *>? { 12 | if (getRawType(returnType) != LiveData::class.java) { 13 | return null 14 | } 15 | val observableType = getParameterUpperBound(0, returnType as ParameterizedType) 16 | val rawObservableType = getRawType(observableType) 17 | require(rawObservableType == ApiResponse::class.java) { "type must be a resource" } 18 | require(observableType is ParameterizedType) { "resource must be parameterized" } 19 | val bodyType = getParameterUpperBound(0, observableType) 20 | return LiveDataCallAdapter(bodyType) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/auth/db/AuthDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.auth.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy 7 | import androidx.room.Query 8 | import com.cn29.aac.repo.user.LoginBean 9 | 10 | @Dao 11 | interface AuthDao { 12 | @Query("SELECT * FROM Auth Where email = :email limit 1") 13 | fun getLogin(email: String?): LiveData 14 | 15 | @Insert(onConflict = OnConflictStrategy.REPLACE) 16 | fun insert(loginBean: LoginBean?): Long 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/auth/db/AuthDb.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.auth.db 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | import com.cn29.aac.repo.user.LoginBean 6 | 7 | @Database(entities = [LoginBean::class], version = 1) 8 | abstract class AuthDb : RoomDatabase() { 9 | abstract fun authDao(): AuthDao 10 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/auth/remote/FacebookAuth.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.auth.remote 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import com.cn29.aac.datasource.api.ApiResponse 6 | import com.cn29.aac.repo.user.LoginBean 7 | import retrofit2.Response 8 | 9 | class FacebookAuth { 10 | fun getLogin(email: String?): LiveData> { 11 | val liveData = MutableLiveData>() 12 | val loginBean = LoginBean(email!!, "Facebook") 13 | loginBean.isLogin = 1 14 | liveData.value = ApiResponse(Response.success(loginBean)) 15 | return liveData 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/auth/remote/GoogleAuth.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.auth.remote 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import com.cn29.aac.datasource.api.ApiResponse 6 | import com.cn29.aac.repo.user.LoginBean 7 | import retrofit2.Response 8 | 9 | class GoogleAuth { 10 | fun getLogin(email: String?): LiveData> { 11 | val liveData = MutableLiveData>() 12 | val loginBean = LoginBean(email!!, "Google") 13 | loginBean.isLogin = 1 14 | liveData.value = ApiResponse(Response.success(loginBean)) 15 | return liveData 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/auth/remote/MyCompanyAuth.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.auth.remote 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import com.cn29.aac.datasource.api.ApiResponse 6 | import com.cn29.aac.repo.user.LoginBean 7 | import retrofit2.Response 8 | 9 | class MyCompanyAuth { 10 | fun getLogin(email: String?): LiveData> { 11 | val liveData = MutableLiveData>() 12 | val loginBean = LoginBean(email!!, "MyCompany") 13 | loginBean.isLogin = 1 14 | liveData.value = ApiResponse(Response.success(loginBean)) 15 | return liveData 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/feedentry/db/AppDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.feedentry.db 2 | 3 | import android.content.Context 4 | import androidx.room.Database 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.cn29.aac.datasource.feedentry.db.migration.Migration1_2 8 | import com.cn29.aac.datasource.feedentry.db.migration.Migration2_3 9 | import com.cn29.aac.repo.feedentry.FeedEntry 10 | 11 | @Database(entities = [FeedEntry::class], version = 3) 12 | abstract class AppDatabase : RoomDatabase() { 13 | abstract fun feedEntryDao(): FeedEntryDAO 14 | 15 | companion object { 16 | private lateinit var appDatabase: AppDatabase 17 | 18 | @JvmStatic 19 | fun getDb(context: Context?): AppDatabase { 20 | appDatabase = Room.databaseBuilder(context!!, 21 | AppDatabase::class.java, 22 | "feedentry-db") 23 | .fallbackToDestructiveMigration() 24 | .addMigrations(Migration1_2.newInstance(), 25 | Migration2_3.newInstance()) 26 | .build() 27 | return appDatabase 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/feedentry/db/FeedEntryDAO.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.feedentry.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.* 5 | import com.cn29.aac.repo.feedentry.FeedEntry 6 | 7 | @Dao 8 | interface FeedEntryDAO { 9 | @Query("SELECT * FROM feedEntrys") 10 | fun getAll(): LiveData> 11 | 12 | @Query("SELECT * FROM feedEntrys WHERE uid = :uid LIMIT 1") 13 | fun findByUid(uid: Int): LiveData 14 | 15 | @Insert 16 | fun insertAll(vararg feedEntries: FeedEntry?): List 17 | 18 | @Delete 19 | fun delete(feedEntry: FeedEntry?): Int? 20 | 21 | @Update 22 | fun update(feedEntry: FeedEntry?): Int? 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/feedentry/db/migration/Migration1_2.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.feedentry.db.migration 2 | 3 | import androidx.room.migration.Migration 4 | import androidx.sqlite.db.SupportSQLiteDatabase 5 | 6 | class Migration1_2(startVersion: Int, 7 | endVersion: Int) : Migration(startVersion, endVersion) { 8 | override fun migrate(database: SupportSQLiteDatabase) { 9 | database.execSQL("ALTER TABLE feedEntrys ADD COLUMN imageUrl TEXT ") 10 | } 11 | 12 | companion object { 13 | @JvmStatic 14 | fun newInstance(): Migration1_2 { 15 | return Migration1_2(1, 2) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/feedentry/db/migration/Migration2_3.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.feedentry.db.migration 2 | 3 | import androidx.room.migration.Migration 4 | import androidx.sqlite.db.SupportSQLiteDatabase 5 | 6 | class Migration2_3(startVersion: Int, 7 | endVersion: Int) : Migration(startVersion, endVersion) { 8 | override fun migrate(database: SupportSQLiteDatabase) { 9 | database.execSQL("ALTER TABLE feedEntrys ADD COLUMN favourite INTEGER NOT NULL DEFAULT 0 ") 10 | } 11 | 12 | companion object { 13 | @JvmStatic 14 | fun newInstance(): Migration2_3 { 15 | return Migration2_3(2, 3) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/github/db/GithubDb.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.cn29.aac.datasource.github.db 17 | 18 | import androidx.room.Database 19 | import androidx.room.RoomDatabase 20 | import com.cn29.aac.repo.github.Contributor 21 | import com.cn29.aac.repo.github.Repo 22 | import com.cn29.aac.repo.github.RepoSearchResult 23 | import com.cn29.aac.repo.github.User 24 | 25 | @Database(entities = [User::class, Repo::class, Contributor::class, RepoSearchResult::class], version = 3) 26 | abstract class GithubDb : RoomDatabase() { 27 | abstract fun userDao(): UserDao 28 | abstract fun repoDao(): RepoDao 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/github/db/RepoDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.github.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy 7 | import androidx.room.Query 8 | import com.cn29.aac.repo.github.Contributor 9 | import com.cn29.aac.repo.github.Repo 10 | import com.cn29.aac.repo.github.RepoSearchResult 11 | 12 | @Dao 13 | interface RepoDao { 14 | @Insert(onConflict = OnConflictStrategy.REPLACE) 15 | fun insert(vararg repos: Repo?) 16 | 17 | @Insert(onConflict = OnConflictStrategy.REPLACE) 18 | fun insertContributors(contributors: List?) 19 | 20 | @Insert(onConflict = OnConflictStrategy.REPLACE) 21 | fun insertRepos(repositories: List?) 22 | 23 | @Insert(onConflict = OnConflictStrategy.IGNORE) 24 | fun createRepoIfNotExists(repo: Repo?): Long 25 | 26 | @Query("SELECT * FROM repo WHERE owner_login = :login AND name = :name") 27 | fun load(login: String?, 28 | name: String?): LiveData 29 | 30 | @Query("SELECT login, avatarUrl,repoName, repoOwner, contributions FROM contributor " 31 | + "WHERE repoName = :name AND repoOwner = :owner " 32 | + "ORDER BY contributions DESC") 33 | fun loadContributors(owner: String?, 34 | name: String?): LiveData> 35 | 36 | @Query("SELECT * FROM Repo " 37 | + "WHERE owner_login = :owner " 38 | + "ORDER BY stars DESC") 39 | fun loadRepositories(owner: String?): LiveData> 40 | 41 | @Insert(onConflict = OnConflictStrategy.REPLACE) 42 | fun insert(result: RepoSearchResult?) 43 | 44 | @Query("SELECT * FROM Repo WHERE id in (:repoIds)") 45 | fun loadById(repoIds: List): LiveData> 46 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/github/db/UserDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.github.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy 7 | import androidx.room.Query 8 | import com.cn29.aac.repo.github.User 9 | 10 | @Dao 11 | interface UserDao { 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insert(user: User?) 14 | 15 | @Query("SELECT * FROM user WHERE login = :login") 16 | fun findByLogin(login: String?): LiveData 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/github/remote/GithubService.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.github.remote 2 | 3 | import androidx.lifecycle.LiveData 4 | import com.cn29.aac.datasource.api.ApiResponse 5 | import com.cn29.aac.repo.github.Contributor 6 | import com.cn29.aac.repo.github.Repo 7 | import com.cn29.aac.repo.github.User 8 | import retrofit2.Call 9 | import retrofit2.http.GET 10 | import retrofit2.http.Path 11 | import retrofit2.http.Query 12 | 13 | interface GithubService { 14 | @GET("users/{login}") 15 | fun getUser(@Path("login") login: String?): LiveData?>? 16 | 17 | @GET("users/{login}/repos") 18 | fun getRepos(@Path("login") login: String?): LiveData?>?>? 19 | 20 | @GET("repos/{owner}/{name}") 21 | fun getRepo(@Path("owner") owner: String?, @Path("name") name: String?): LiveData?>? 22 | 23 | @GET("repos/{owner}/{name}/contributors") 24 | fun getContributors(@Path("owner") owner: String?, 25 | @Path("name") name: String?): LiveData?>?>? 26 | 27 | @GET("search/repositories") 28 | fun searchRepos(@Query("q") query: String?): LiveData?>? 29 | 30 | @GET("search/repositories") 31 | fun searchRepos(@Query("q") query: String?, @Query("page") page: Int): Call? 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/github/remote/GithubTypeConverters.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.github.remote 2 | 3 | import androidx.room.TypeConverter 4 | 5 | object GithubTypeConverters { 6 | @TypeConverter 7 | fun stringToIntList(data: String): List = 8 | data.split(",").filter { it.toIntOrNull() != null } 9 | .map { it.toInt() } 10 | 11 | @JvmStatic 12 | @TypeConverter 13 | fun intListToString(ints: List): String = 14 | ints.joinToString(separator = ",") 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/github/remote/RepoSearchResponse.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.github.remote 2 | 3 | import com.cn29.aac.repo.github.Repo 4 | import com.google.gson.annotations.SerializedName 5 | import java.util.* 6 | 7 | class RepoSearchResponse { 8 | @SerializedName("total_count") 9 | var total = 0 10 | @SerializedName("items") 11 | var items: List? = null 12 | var nextPage: Int? = null 13 | 14 | val repoIds: List 15 | get() { 16 | val repoIds: MutableList = ArrayList() 17 | for (repo in items!!) { 18 | repoIds.add(repo.id) 19 | } 20 | return repoIds 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/itunes/db/AlbumDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.itunes.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.* 5 | import com.cn29.aac.repo.itunes.Album 6 | 7 | @Dao 8 | interface AlbumDao { 9 | @Insert(onConflict = OnConflictStrategy.REPLACE) 10 | fun insert(vararg artists: Album?) 11 | 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insert(artists: List) 14 | 15 | @Query("SELECT * FROM album") 16 | fun getAll(): LiveData> 17 | 18 | @Query("SELECT * FROM album WHERE artistId = :artistId ") 19 | fun getAlbum(artistId: Long): LiveData> 20 | 21 | @Update 22 | fun update(artist: Album): Int 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/itunes/db/ArtistDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.itunes.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.* 5 | import com.cn29.aac.repo.itunes.Artist 6 | 7 | @Dao 8 | interface ArtistDao { 9 | @Insert(onConflict = OnConflictStrategy.REPLACE) 10 | fun insert(vararg artists: Artist?) 11 | 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insert(artists: List?) 14 | 15 | @Query("SELECT * FROM artist WHERE artistName like '%' || :query || '%'") 16 | fun getArtists(query: String): LiveData> 17 | 18 | @Update 19 | fun update(artist: Artist): Int 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/itunes/db/ItunesDb.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.itunes.db 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | import com.cn29.aac.repo.itunes.Album 6 | import com.cn29.aac.repo.itunes.Artist 7 | 8 | @Database(entities = [Artist::class, Album::class], version = 3) 9 | abstract class ItunesDb : RoomDatabase() { 10 | abstract fun artistDao(): ArtistDao 11 | abstract fun albumDao(): AlbumDao 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/itunes/remote/ItunesService.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.itunes.remote 2 | 3 | import androidx.lifecycle.LiveData 4 | import com.cn29.aac.datasource.api.ApiResponse 5 | import com.cn29.aac.repo.itunes.AlbumSearchResult 6 | import com.cn29.aac.repo.itunes.ArtistSearchResult 7 | import retrofit2.http.GET 8 | import retrofit2.http.Query 9 | 10 | interface ItunesService { 11 | @GET("search") 12 | fun getArtistSearchResult(@Query("term") searchTerm: String?): LiveData?>? 13 | 14 | /* 15 | Look up all albums for Jack Johnson: https://itunes.apple.com/lookup?id=909253&entity=album. 16 | */ 17 | @GET("lookup") 18 | fun getAlbumSearchResult(@Query("id") artistId: Int, 19 | @Query("entity") entity: String?): LiveData?>? 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/order/db/OrderDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.order.db 2 | 3 | class OrderDao -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/order/db/OrderDb.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.order.db 2 | 3 | class OrderDb -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/shoppingkart/db/KartDao.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.shoppingkart.db 2 | 3 | class KartDao -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/datasource/shoppingkart/db/KartDb.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.datasource.shoppingkart.db 2 | 3 | class KartDb -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/di/AppComponent.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.di 2 | 3 | import android.app.Application 4 | import com.cn29.aac.MyApplication 5 | import com.cn29.aac.di.datasources.db.RoomModule 6 | import com.cn29.aac.di.datasources.remote.AuthModule 7 | import com.cn29.aac.di.datasources.remote.RESTModule 8 | import com.cn29.aac.di.repo.RepoModule 9 | import com.cn29.aac.di.ui.UiBuilder 10 | import dagger.BindsInstance 11 | import dagger.Component 12 | import dagger.android.AndroidInjectionModule 13 | import dagger.android.support.AndroidSupportInjectionModule 14 | import javax.inject.Singleton 15 | 16 | /** 17 | * Created by Charles Ng on 27/9/2017. 18 | */ 19 | @Singleton 20 | @Component(modules = [ //necessary modules 21 | AndroidInjectionModule::class, AndroidSupportInjectionModule::class, //app modules 22 | AppModule::class, //repo modules 23 | RepoModule::class, //datasource modules 24 | RESTModule::class, RoomModule::class, AuthModule::class, //ui modules 25 | UiBuilder::class]) 26 | interface AppComponent { 27 | fun inject(app: MyApplication) 28 | 29 | @Component.Builder 30 | interface Builder { 31 | @BindsInstance 32 | fun application(application: Application): Builder 33 | fun build(): AppComponent 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/di/AppModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.di 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import android.content.SharedPreferences 6 | import android.preference.PreferenceManager 7 | import dagger.Module 8 | import dagger.Provides 9 | import javax.inject.Singleton 10 | 11 | /** 12 | * Created by Charles Ng on 27/9/2017. 13 | */ 14 | @Module 15 | class AppModule { 16 | @Singleton 17 | @Provides 18 | fun provideContext(application: Application): Context { 19 | return application 20 | } 21 | 22 | @Singleton 23 | @Provides 24 | fun provideDefaultSharedPreferences(application: Application): SharedPreferences { 25 | return PreferenceManager.getDefaultSharedPreferences(application) 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/di/datasources/remote/AuthModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.di.datasources.remote 2 | 3 | import android.app.Application 4 | import com.cn29.aac.datasource.auth.remote.FacebookAuth 5 | import com.cn29.aac.datasource.auth.remote.GoogleAuth 6 | import com.cn29.aac.datasource.auth.remote.MyCompanyAuth 7 | import dagger.Module 8 | import dagger.Provides 9 | import javax.inject.Singleton 10 | 11 | /** 12 | * Created by Charles Ng on 13/10/2017. 13 | */ 14 | @Module 15 | class AuthModule { 16 | @Singleton 17 | @Provides 18 | fun provideGoogleAuth(application: Application?): GoogleAuth { 19 | return GoogleAuth() 20 | } 21 | 22 | @Singleton 23 | @Provides 24 | fun provideFacebookAuth(application: Application?): FacebookAuth { 25 | return FacebookAuth() 26 | } 27 | 28 | @Singleton 29 | @Provides 30 | fun provideMyCompanyAuth(application: Application?): MyCompanyAuth { 31 | return MyCompanyAuth() 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/di/repo/RepoModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.di.repo 2 | 3 | import dagger.Module 4 | 5 | /** 6 | * Created by charlesng0209 on 2/10/2017. 7 | */ 8 | @Module 9 | class RepoModule -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/di/scope/AndroidDataBinding.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.di.scope 2 | 3 | /** 4 | * Created by Charles Ng on 23/10/2017. 5 | */ 6 | annotation class AndroidDataBinding -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/di/scope/ViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.di.scope 2 | 3 | /** 4 | * Created by Charles Ng on 23/10/2017. 5 | */ 6 | annotation class ViewModel -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/feedentry/FeedEntry.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.feedentry 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Entity(tableName = "feedEntrys") 8 | data class FeedEntry(@ColumnInfo(name = "title") var title: String, 9 | @ColumnInfo(name = "subtitle") var subTitle: String, 10 | @ColumnInfo(name = "favourite") var isFavourite: Boolean = false, 11 | @JvmField @ColumnInfo(name = "imageUrl") var imageUrl: String? = null, 12 | @JvmField @PrimaryKey(autoGenerate = true) var uid: Int = 0) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/feedentry/FeedEntryRepository.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.feedentry 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import androidx.lifecycle.LiveData 6 | import com.cn29.aac.datasource.feedentry.db.AppDatabase.Companion.getDb 7 | import com.cn29.aac.datasource.feedentry.db.FeedEntryDAO 8 | import javax.inject.Inject 9 | import javax.inject.Singleton 10 | 11 | /** 12 | * Created by Charles Ng on 6/9/2017. 13 | * Implements the FeedEntryDAO interface to handle all the situation 14 | */ 15 | @Singleton 16 | class FeedEntryRepository @Inject constructor(application: Application?) : 17 | FeedEntryDAO { 18 | private lateinit var feedEntryDAO: FeedEntryDAO 19 | fun init(context: Context?) { 20 | val db = getDb(context) 21 | feedEntryDAO = db.feedEntryDao() 22 | } 23 | 24 | override fun getAll(): LiveData> { 25 | return feedEntryDAO.getAll() 26 | } 27 | 28 | override fun findByUid(uid: Int): LiveData { 29 | return feedEntryDAO.findByUid(uid) 30 | } 31 | 32 | override fun insertAll(vararg feedEntries: FeedEntry?): List = 33 | feedEntryDAO.insertAll(*feedEntries) 34 | 35 | override fun delete(feedEntry: FeedEntry?): Int? { 36 | return feedEntryDAO.delete(feedEntry) 37 | } 38 | 39 | override fun update(feedEntry: FeedEntry?): Int? { 40 | return feedEntryDAO.update(feedEntry) 41 | } 42 | 43 | init { 44 | init(application) 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/github/Contributor.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.github 2 | 3 | import androidx.room.Entity 4 | import androidx.room.ForeignKey 5 | import com.google.gson.annotations.SerializedName 6 | 7 | @Entity(primaryKeys = ["repoName", "repoOwner", "login"], 8 | foreignKeys = [ForeignKey(entity = Repo::class, 9 | parentColumns = ["name", "owner_login"], 10 | childColumns = ["repoName", "repoOwner"], 11 | onUpdate = ForeignKey.CASCADE, 12 | deferred = true)]) 13 | class Contributor(@field:SerializedName("login") val login: String, 14 | @field:SerializedName("contributions") val contributions: Int, 15 | @field:SerializedName("avatar_url") val avatarUrl: String, 16 | @field:SerializedName("repoName") val repoName: String, 17 | @field:SerializedName("repoOwner") val repoOwner: String) { 18 | 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/github/Repo.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.github 2 | 3 | import androidx.room.Embedded 4 | import androidx.room.Entity 5 | import androidx.room.Index 6 | import com.google.gson.annotations.SerializedName 7 | 8 | @Entity(indices = [Index("id"), Index("owner_login")], 9 | primaryKeys = ["name", "owner_login"]) 10 | data class Repo(val id: Int, 11 | @JvmField @SerializedName("name") val name: String, 12 | @JvmField @SerializedName("full_name") val fullName: String, 13 | @JvmField @SerializedName("description") val description: String? = "", 14 | @JvmField @Embedded(prefix = "owner_") @field:SerializedName("owner") val owner: Owner, 15 | @JvmField @SerializedName("stargazers_count") val stars: Int) { 16 | 17 | data class Owner(@JvmField @field:SerializedName("login") val login: String, 18 | @JvmField @SerializedName("url") val url: String?) 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/github/RepoSearchResult.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.cn29.aac.repo.github 17 | 18 | import androidx.room.Entity 19 | import androidx.room.TypeConverters 20 | import com.cn29.aac.datasource.github.remote.GithubTypeConverters 21 | 22 | @Entity(primaryKeys = ["query"]) 23 | @TypeConverters(GithubTypeConverters::class) 24 | class RepoSearchResult(val query: String, 25 | val repoIds: List, 26 | val totalCount: Int, 27 | val next: Int?) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/github/User.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.github 2 | 3 | import androidx.room.Entity 4 | import com.google.gson.annotations.SerializedName 5 | 6 | /** 7 | * Created by Charles Ng on 3/10/2017. 8 | */ 9 | @Entity(primaryKeys = ["login"]) 10 | data class User(@field:SerializedName("login") val login: String, 11 | @field:SerializedName("avatar_url") val avatarUrl: String, 12 | @field:SerializedName("name") val name: String, 13 | @field:SerializedName("company") val company: String, 14 | @field:SerializedName("repos_url") val reposUrl: String, 15 | @field:SerializedName("blog") val blog: String) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/itunes/Album.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.itunes 2 | 3 | import androidx.room.Entity 4 | import androidx.room.Index 5 | 6 | /** 7 | * Created by Charles Ng on 20/10/2017. 8 | */ 9 | @Entity(indices = [Index("artistId")], 10 | primaryKeys = ["artistId", "collectionName"]) 11 | data class Album(var artistId: Long = 0, 12 | var collectionName: String = "", 13 | var collectionPrice: Double = 0.0, 14 | var primaryGenreName: String? = null, 15 | var releaseDate: String? = null, 16 | var artworkUrl100: String? = null, 17 | var collectionViewUrl: String? = null) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/itunes/AlbumSearchResult.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.itunes 2 | 3 | /** 4 | * Created by Charles Ng on 20/10/2017. 5 | */ 6 | data class AlbumSearchResult(val resultCount: Int = 0, 7 | var results: List? = null) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/itunes/Artist.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.itunes 2 | 3 | import android.os.Parcelable 4 | import androidx.room.Entity 5 | import androidx.room.Index 6 | import androidx.room.TypeConverters 7 | import com.cn29.aac.repo.util.TypeConvertor 8 | import kotlinx.android.parcel.Parcelize 9 | import java.util.* 10 | 11 | /** 12 | * Created by Charles Ng on 16/10/2017. 13 | */ 14 | @Entity(indices = [Index("artistId")], 15 | primaryKeys = ["artistId", "artistName"]) 16 | @TypeConverters( 17 | TypeConvertor::class) 18 | @Parcelize 19 | data class Artist(@JvmField var artistId: Long = 0, 20 | @JvmField var artistName: String, 21 | @JvmField var trackName: String? = null, 22 | @JvmField var artworkUrl100: String? = null, 23 | @JvmField var trackPrice: Double = 0.0, 24 | @JvmField var isFavourite: Boolean = false, 25 | @JvmField var createDate: Date? = null 26 | 27 | ) : Parcelable { 28 | constructor() : this( 29 | artistId = 0, 30 | artistName = "", 31 | trackName = null, 32 | artworkUrl100 = null, 33 | trackPrice = 0.0, 34 | isFavourite = false, 35 | createDate = null 36 | ) 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/itunes/ArtistSearchResult.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.itunes 2 | 3 | import java.util.* 4 | 5 | /** 6 | * Created by Charles Ng on 16/10/2017. 7 | */ 8 | class ArtistSearchResult { 9 | var resultCount = 0 10 | var results: ArrayList? = null 11 | 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/shoppingkart/Kart.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.shoppingkart 2 | 3 | /** 4 | * Created by Charles Ng on 25/10/2017. 5 | */ 6 | class Kart { 7 | var trackId = 0 8 | var count = 0 9 | 10 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/shoppingkart/KartRepository.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.shoppingkart 2 | 3 | import com.cn29.aac.AppExecutors 4 | import javax.inject.Inject 5 | import javax.inject.Singleton 6 | 7 | /** 8 | * Created by Charles Ng on 25/10/2017. 9 | */ 10 | @Singleton 11 | class KartRepository @Inject constructor(private val appExecutors: AppExecutors) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/user/LoginBean.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.user 2 | 3 | import androidx.room.Entity 4 | import com.google.gson.annotations.SerializedName 5 | 6 | /** 7 | * Created by Charles Ng on 13/10/2017. 8 | */ 9 | @Entity(tableName = "Auth", primaryKeys = ["email"]) 10 | data class LoginBean(@JvmField @SerializedName("email") var email: String, 11 | @SerializedName("authType") var authType: String, 12 | @JvmField @SerializedName("isLogin") var isLogin: Int = 0, 13 | @JvmField var password: String? = null 14 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/util/RateLimiter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.cn29.aac.repo.util 17 | 18 | import android.os.SystemClock 19 | import androidx.collection.ArrayMap 20 | import java.util.concurrent.TimeUnit 21 | 22 | /** 23 | * Utility class that decides whether we should fetch some data or not. 24 | */ 25 | class RateLimiter(timeout: Int, 26 | timeUnit: TimeUnit) { 27 | private val timeout: Long 28 | private val timestamps = ArrayMap() 29 | 30 | @Synchronized 31 | fun shouldFetch(key: KEY): Boolean { 32 | val lastFetched = timestamps[key] 33 | val now = now() 34 | if (lastFetched == null) { 35 | timestamps[key] = now 36 | return true 37 | } 38 | if (now - lastFetched > timeout) { 39 | timestamps[key] = now 40 | return true 41 | } 42 | return false 43 | } 44 | 45 | private fun now(): Long { 46 | return SystemClock.uptimeMillis() 47 | } 48 | 49 | @Synchronized 50 | fun reset(key: KEY) { 51 | timestamps.remove(key) 52 | } 53 | 54 | init { 55 | this.timeout = timeUnit.toMillis(timeout.toLong()) 56 | } 57 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/util/Resource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.cn29.aac.repo.util 17 | 18 | /** 19 | * A generic class that holds a value with its loading status. 20 | */ 21 | class Resource(@JvmField val status: Status, 22 | @JvmField val data: T?, 23 | val message: String?) { 24 | 25 | companion object { 26 | @JvmStatic 27 | fun success(data: T?): Resource { 28 | return Resource(Status.SUCCESS, data, null) 29 | } 30 | 31 | @JvmStatic 32 | fun error(msg: String?, 33 | data: T?): Resource { 34 | return Resource(Status.ERROR, data, msg) 35 | } 36 | 37 | @JvmStatic 38 | fun loading(data: T?): Resource { 39 | return Resource(Status.LOADING, data, null) 40 | } 41 | 42 | @JvmStatic 43 | fun checking(data: T?): Resource { 44 | return Resource(Status.CHECKING, data, null) 45 | } 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/util/Status.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.cn29.aac.repo.util 17 | 18 | /** 19 | * Status of a resource that is provided to the UI. 20 | * 21 | * 22 | * These are usually created by the Repository classes where they return 23 | * `LiveData>` to pass back the latest data to the UI with its fetch status. 24 | */ 25 | enum class Status { 26 | CHECKING, SUCCESS, ERROR, LOADING 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/repo/util/TypeConvertor.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.repo.util 2 | 3 | import androidx.room.TypeConverter 4 | import java.text.ParseException 5 | import java.text.SimpleDateFormat 6 | import java.util.* 7 | 8 | /** 9 | * Created by Charles Ng on 19/10/2017. 10 | */ 11 | object TypeConvertor { 12 | private const val DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 13 | 14 | @JvmStatic 15 | @TypeConverter 16 | fun stringToIntList(date: Date?): String { 17 | return if (date != null) { 18 | SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).format(date) 19 | } else SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).format(Date()) 20 | } 21 | 22 | @JvmStatic 23 | @TypeConverter 24 | fun intListToString(date: String): Date { 25 | return if (date != "") { 26 | try { 27 | SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).parse(date) 28 | } catch (e: ParseException) { 29 | e.printStackTrace() 30 | Date() 31 | } 32 | } else Date() 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/base/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.base 2 | 3 | import android.os.Bundle 4 | import com.cn29.aac.ui.common.AlertDialogComponent 5 | import com.cn29.aac.ui.common.FragmentPermissionComponent.PermissionCallback 6 | import com.cn29.aac.ui.common.ProgressDialogComponent 7 | import dagger.android.support.DaggerFragment 8 | 9 | /** 10 | * Created by charlesng0209 on 2/10/2017. 11 | */ 12 | open class BaseFragment : 13 | DaggerFragment() { 14 | //common UI component 15 | @JvmField 16 | protected var progressDialogComponent: ProgressDialogComponent? = null 17 | private var dialogComponent: AlertDialogComponent? = null 18 | 19 | //permission callback 20 | private var permissionCallback: PermissionCallback? = null 21 | override fun onActivityCreated(savedInstanceState: Bundle?) { 22 | super.onActivityCreated(savedInstanceState) 23 | progressDialogComponent = activity?.let { 24 | ProgressDialogComponent(it, 25 | this.lifecycle) 26 | } 27 | dialogComponent = activity?.let { 28 | AlertDialogComponent(it, 29 | this.lifecycle) 30 | } 31 | } 32 | 33 | override fun onRequestPermissionsResult(requestCode: Int, 34 | permissions: Array, 35 | grantResults: IntArray) { 36 | permissionCallback!!.onRequestPermissionsResult(requestCode, 37 | permissions, 38 | grantResults) 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/common/ActivityPermissionComponent.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.common 2 | 3 | import android.app.Activity 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.lifecycle.Lifecycle 6 | import androidx.lifecycle.LifecycleObserver 7 | import androidx.lifecycle.OnLifecycleEvent 8 | 9 | /** 10 | * Created by Charles Ng on 13/10/2017. 11 | */ 12 | class ActivityPermissionComponent(activity: AppCompatActivity, 13 | permissions: Array, 14 | requestCode: Int) : 15 | LifecycleObserver { 16 | private val activity: Activity 17 | private val permissions: Array 18 | private val requestCode: Int 19 | 20 | @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) 21 | fun onCreate() { 22 | } 23 | 24 | init { 25 | this.activity = activity 26 | this.permissions = permissions 27 | this.requestCode = requestCode 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/common/ActivityPermissionComponentBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.common 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | 5 | class ActivityPermissionComponentBuilder(private val activity: AppCompatActivity) { 6 | private lateinit var permissions: Array 7 | private var requestCode = 0 8 | fun setPermissions(permissions: Array): ActivityPermissionComponentBuilder { 9 | this.permissions = permissions 10 | return this 11 | } 12 | 13 | fun setRequestCode(requestCode: Int): ActivityPermissionComponentBuilder { 14 | this.requestCode = requestCode 15 | return this 16 | } 17 | 18 | fun createActivityPermissionComponent(): ActivityPermissionComponent { 19 | return ActivityPermissionComponent(activity, permissions, requestCode) 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/common/AlertDialogComponent.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.common 2 | 3 | import android.app.AlertDialog 4 | import android.content.Context 5 | import androidx.lifecycle.Lifecycle 6 | import androidx.lifecycle.LifecycleObserver 7 | import androidx.lifecycle.OnLifecycleEvent 8 | 9 | /** 10 | * Created by Charles Ng on 12/10/2017. 11 | */ 12 | class AlertDialogComponent(private val context: Context, 13 | lifecycle: Lifecycle) : 14 | LifecycleObserver { 15 | private var alertDialog: AlertDialog? = null 16 | fun showDialog(alertDialog: AlertDialog) { 17 | this.alertDialog = alertDialog 18 | alertDialog.show() 19 | } 20 | 21 | fun hideDialog() { 22 | if (alertDialog != null) { 23 | alertDialog!!.dismiss() 24 | } 25 | } 26 | 27 | @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) 28 | fun onCreate() { 29 | } 30 | 31 | @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) 32 | fun onPause() { 33 | if (alertDialog != null) { 34 | alertDialog!!.dismiss() 35 | } 36 | } 37 | 38 | @OnLifecycleEvent(Lifecycle.Event.ON_STOP) 39 | fun stop() { 40 | if (alertDialog != null) { 41 | alertDialog!!.dismiss() 42 | } 43 | } 44 | 45 | init { 46 | lifecycle.addObserver(this) 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/common/FragmentPermissionComponent.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.common 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.lifecycle.Lifecycle 5 | import androidx.lifecycle.LifecycleObserver 6 | import androidx.lifecycle.OnLifecycleEvent 7 | 8 | /** 9 | * Created by Charles Ng on 12/10/2017. 10 | */ 11 | class FragmentPermissionComponent(private val fragment: Fragment, 12 | private val permissions: Array, 13 | private val requestCode: Int) : 14 | LifecycleObserver { 15 | @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) 16 | fun onCreate() { 17 | fragment.requestPermissions(permissions, requestCode) 18 | } 19 | 20 | interface PermissionCallback { 21 | fun onRequestPermissionsResult(requestCode: Int, 22 | permissions: Array, 23 | grantResults: IntArray) 24 | } 25 | 26 | init { 27 | fragment.lifecycle.addObserver(this) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/common/PermissionComponentBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.common 2 | 3 | import androidx.fragment.app.Fragment 4 | 5 | class PermissionComponentBuilder(private val fragment: Fragment) { 6 | private lateinit var permissions: Array 7 | private var requestCode = 0 8 | fun setPermissions(permissions: Array): PermissionComponentBuilder { 9 | this.permissions = permissions 10 | return this 11 | } 12 | 13 | fun setRequestCode(requestCode: Int): PermissionComponentBuilder { 14 | this.requestCode = requestCode 15 | return this 16 | } 17 | 18 | fun createPermissionComponent(): FragmentPermissionComponent { 19 | return FragmentPermissionComponent(fragment, permissions, requestCode) 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/feedentry/FeedActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.feedentry 2 | 3 | import android.view.LayoutInflater 4 | import androidx.databinding.DataBindingUtil 5 | import androidx.lifecycle.ViewModelProvider 6 | import com.cn29.aac.R 7 | import com.cn29.aac.databinding.DialogFeedentryBinding 8 | import com.cn29.aac.repo.feedentry.FeedEntry 9 | import com.cn29.aac.ui.feedentry.vm.FeedEntryListViewModel 10 | import com.cn29.aac.ui.feedentry.vm.FeedEntryListViewModelFactory 11 | import dagger.Module 12 | import dagger.Provides 13 | 14 | @Module 15 | class FeedActivityModule { 16 | @Provides 17 | fun provideViewModel(feedEntry: FeedEntry, 18 | feedActivity: FeedActivity, 19 | factory: FeedEntryListViewModelFactory): FeedEntryListViewModel { 20 | val viewModel = ViewModelProvider(feedActivity, factory).get( 21 | FeedEntryListViewModel::class.java) 22 | viewModel.feedEntry.set(feedEntry) 23 | return viewModel 24 | } 25 | 26 | @Provides 27 | fun provideDialogBinding(activity: FeedActivity, 28 | feedEntryListViewModel: FeedEntryListViewModel): DialogFeedentryBinding { 29 | val binding: DialogFeedentryBinding = DataBindingUtil 30 | .inflate(LayoutInflater.from(activity), 31 | R.layout.dialog_feedentry, 32 | null, 33 | false) 34 | binding.feedEntry = feedEntryListViewModel.feedEntry.get() 35 | return binding 36 | } 37 | 38 | @Provides 39 | fun provideDefaultFeedEntry(): FeedEntry { 40 | return FeedEntry("abc", "", false, null, 0) 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/feedentry/FeedEntryFragmentModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.feedentry 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.FragmentFeedentryListBinding 7 | import com.cn29.aac.ui.feedentry.vm.FeedEntryListViewModel 8 | import com.cn29.aac.ui.feedentry.vm.FeedEntryListViewModelFactory 9 | import dagger.Module 10 | import dagger.Provides 11 | 12 | @Module 13 | class FeedEntryFragmentModule { 14 | @Provides 15 | fun provideViewModel(feedEntryFragment: FeedEntryFragment, 16 | factory: FeedEntryListViewModelFactory): FeedEntryListViewModel { 17 | return ViewModelProvider(feedEntryFragment.requireActivity(), factory) 18 | .get(FeedEntryListViewModel::class.java) 19 | } 20 | 21 | @Provides 22 | fun provideDataBinding(feedEntryFragment: FeedEntryFragment): FragmentFeedentryListBinding { 23 | return DataBindingUtil 24 | .inflate(feedEntryFragment.activity!!.layoutInflater, 25 | R.layout.fragment_feedentry_list, null, 26 | false) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/feedentry/vm/FeedEntryListViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.feedentry.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.feedentry.FeedEntryRepository 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by Charles Ng on 20/9/2017. 10 | */ 11 | class FeedEntryListViewModelFactory @Inject constructor(private val feedEntryRepository: FeedEntryRepository) : 12 | NewInstanceFactory() { 13 | override fun create(modelClass: Class): T { 14 | return FeedEntryListViewModel(feedEntryRepository) as T 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/feedentrydetail/vm/FeedEntryDetailViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.feedentrydetail.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.cn29.aac.repo.feedentry.FeedEntry 6 | import com.cn29.aac.repo.feedentry.FeedEntryRepository 7 | 8 | /** 9 | * Created by Charles Ng on 11/9/2017. 10 | */ 11 | class FeedEntryDetailViewModel(private val feedEntryDBRepository: FeedEntryRepository, 12 | uid: Int) : 13 | ViewModel() { 14 | private var feedEntry: LiveData 15 | fun getFeedEntry(uid: Int): LiveData { 16 | feedEntry = feedEntryDBRepository.findByUid(uid) 17 | return feedEntry 18 | } 19 | 20 | fun update(feedEntry: FeedEntry?): Int { 21 | return feedEntryDBRepository.update(feedEntry)!! 22 | } 23 | 24 | init { 25 | feedEntry = feedEntryDBRepository.findByUid(uid) 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/feedentrydetail/vm/FeedEntryDetailViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.feedentrydetail.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.feedentry.FeedEntryRepository 6 | 7 | /** 8 | * Created by Charles Ng on 20/9/2017. 9 | */ 10 | class FeedEntryDetailViewModelFactory(private val feedEntryRepository: FeedEntryRepository, 11 | uid: Int) : 12 | NewInstanceFactory() { 13 | private var uid = 0 14 | override fun create(modelClass: Class): T { 15 | return FeedEntryDetailViewModel(feedEntryRepository, uid) as T 16 | } 17 | 18 | init { 19 | this.uid = uid 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/location/LocationActivity.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.location 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.widget.Toolbar 5 | import com.cn29.aac.R 6 | import com.cn29.aac.ui.base.BaseAppCompatActivity 7 | import com.cn29.aac.ui.location.vm.LastLocationViewModel 8 | import javax.inject.Inject 9 | 10 | class LocationActivity : BaseAppCompatActivity() { 11 | @JvmField 12 | @Inject 13 | var lastLocationViewModel: LastLocationViewModel? = null 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_location) 17 | val toolbar = findViewById( 18 | R.id.toolbar) 19 | setSupportActionBar(toolbar) 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/location/LocationActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.location 2 | 3 | import androidx.lifecycle.ViewModelProvider 4 | import com.cn29.aac.ui.location.vm.LastLocationViewModel 5 | import com.cn29.aac.ui.location.vm.LastLocationViewModelFactory 6 | import dagger.Module 7 | import dagger.Provides 8 | 9 | /** 10 | * Created by charlesng0209 on 2/10/2017. 11 | */ 12 | @Module 13 | class LocationActivityModule { 14 | @Provides 15 | fun provideLastLocationVM(factory: LastLocationViewModelFactory, 16 | activity: LocationActivity): LastLocationViewModel { 17 | return ViewModelProvider(activity, factory) 18 | .get( 19 | LastLocationViewModel::class.java) 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/location/vm/LastLocationViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.location.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.cn29.aac.repo.itunes.Artist 6 | import com.cn29.aac.repo.itunes.ItunesRepository 7 | import com.cn29.aac.repo.location.LastLocationListener 8 | import com.cn29.aac.repo.util.Resource 9 | 10 | /** 11 | * Created by Charles Ng on 7/9/2017. 12 | */ 13 | class LastLocationViewModel(private val lastLocationListener: LastLocationListener, 14 | private val itunesRepository: ItunesRepository) : 15 | ViewModel() { 16 | val lastKnowLocation: LastLocationListener 17 | get() = lastLocationListener 18 | 19 | fun getSearchResult(searchTerm: String?): LiveData>> { 20 | return itunesRepository.getArtistResult(searchTerm) 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/location/vm/LastLocationViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.location.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.itunes.ItunesRepository 6 | import com.cn29.aac.repo.location.LastLocationListener 7 | import javax.inject.Inject 8 | 9 | /** 10 | * Created by Charles Ng on 20/9/2017. 11 | */ 12 | class LastLocationViewModelFactory @Inject constructor(private val lastLocationListener: LastLocationListener, 13 | private val itunesRepository: ItunesRepository) : 14 | NewInstanceFactory() { 15 | override fun create(modelClass: Class): T { 16 | return LastLocationViewModel(lastLocationListener, 17 | itunesRepository) as T 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/login/vm/LoginViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.login.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.cn29.aac.repo.user.AuthRepository 6 | import com.cn29.aac.repo.user.AuthRepository.AuthMode 7 | import com.cn29.aac.repo.user.LoginBean 8 | import com.cn29.aac.repo.util.Resource 9 | 10 | /** 11 | * Created by Charles Ng on 13/10/2017. 12 | */ 13 | class LoginViewModel(private val authRepository: AuthRepository) : 14 | ViewModel() { 15 | fun login(authMode: AuthMode?, 16 | email: String?, 17 | password: String?): LiveData> { 18 | return authRepository.login(authMode, email, password) 19 | } 20 | 21 | val isLogin: Boolean 22 | get() = authRepository.isLogin 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/login/vm/LoginViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.login.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.user.AuthRepository 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by Charles Ng on 13/10/2017. 10 | */ 11 | class LoginViewModelFactory @Inject constructor(private val authRepository: AuthRepository) : 12 | NewInstanceFactory() { 13 | override fun create(modelClass: Class): T { 14 | return LoginViewModel(authRepository) as T 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/main/AppArchNavigationDrawerModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.main 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.ActivityAppArchNavigationDrawerBinding 7 | import com.cn29.aac.ui.main.vm.AppArchNavViewModel 8 | import com.cn29.aac.ui.main.vm.AppArchNavViewModelFactory 9 | import dagger.Module 10 | import dagger.Provides 11 | 12 | /** 13 | * Created by Charles Ng on 13/10/2017. 14 | */ 15 | @Module 16 | class AppArchNavigationDrawerModule { 17 | @Provides 18 | fun provideVm(drawer: AppArchNavigationDrawer, 19 | factory: AppArchNavViewModelFactory): AppArchNavViewModel { 20 | return ViewModelProvider(drawer, factory).get( 21 | AppArchNavViewModel::class.java) 22 | } 23 | 24 | @Provides 25 | fun provideBinding(drawer: AppArchNavigationDrawer?): ActivityAppArchNavigationDrawerBinding { 26 | return DataBindingUtil.setContentView(drawer!!, 27 | R.layout.activity_app_arch_navigation_drawer) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/main/vm/AppArchNavViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.main.vm 2 | 3 | import android.content.SharedPreferences 4 | import androidx.lifecycle.ViewModel 5 | 6 | /** 7 | * Created by Charles Ng on 13/10/2017. 8 | */ 9 | class AppArchNavViewModel(var sharedPreferences: SharedPreferences) : 10 | ViewModel() { 11 | fun logout() { 12 | sharedPreferences.edit().putBoolean("isLogin", false).apply() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/main/vm/AppArchNavViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.main.vm 2 | 3 | import android.content.SharedPreferences 4 | import androidx.lifecycle.ViewModel 5 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by Charles Ng on 13/10/2017. 10 | */ 11 | class AppArchNavViewModelFactory @Inject constructor(private val sharedPreferences: SharedPreferences) : 12 | NewInstanceFactory() { 13 | override fun create(modelClass: Class): T { 14 | return AppArchNavViewModel(sharedPreferences) as T 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/masterdetail/GithubRepoAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.masterdetail 2 | 3 | import com.cn29.aac.R 4 | import com.cn29.aac.databinding.ItemGithubCardBinding 5 | import com.cn29.aac.repo.github.Repo 6 | import com.cn29.aac.ui.common.BaseRecyclerViewAdapter 7 | import java.util.* 8 | 9 | /** 10 | * Created by Charles Ng on 11/10/2017. 11 | */ 12 | class GithubRepoAdapter( 13 | itemClickListener: OnItemClickListener) : 14 | BaseRecyclerViewAdapter( 15 | itemClickListener) { 16 | private var repos: List = ArrayList() 17 | fun setRepos(repos: List) { 18 | this.repos = repos 19 | } 20 | 21 | override fun getItemForPosition(position: Int): Repo { 22 | return repos[position] 23 | } 24 | 25 | override fun getLayoutIdForPosition(position: Int): Int { 26 | return R.layout.item_github_card 27 | } 28 | 29 | override fun bind(binding: ItemGithubCardBinding, 30 | item: Repo?) { 31 | binding.repo = item 32 | } 33 | 34 | override fun getItemCount(): Int { 35 | return repos.size 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/masterdetail/SimpleDetailActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.masterdetail 2 | 3 | 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.ui.masterdetail.vm.SimpleMasterDetailShareViewModel 6 | import com.cn29.aac.ui.masterdetail.vm.SimpleMasterDetailShareViewModelFactory 7 | import dagger.Module 8 | import dagger.Provides 9 | 10 | /** 11 | * Created by Charles Ng on 3/10/2017. 12 | */ 13 | @Module 14 | class SimpleDetailActivityModule { 15 | @Provides 16 | fun provideVm(simpleDetailActivity: SimpleDetailActivity, 17 | factory: SimpleMasterDetailShareViewModelFactory): SimpleMasterDetailShareViewModel { 18 | return ViewModelProvider(simpleDetailActivity, factory) 19 | .get( 20 | SimpleMasterDetailShareViewModel::class.java) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/masterdetail/SimpleDetailFragmentModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.masterdetail 2 | 3 | import androidx.lifecycle.ViewModelProvider 4 | import com.cn29.aac.ui.masterdetail.vm.SimpleMasterDetailShareViewModel 5 | import com.cn29.aac.ui.masterdetail.vm.SimpleMasterDetailShareViewModelFactory 6 | import dagger.Module 7 | import dagger.Provides 8 | 9 | /** 10 | * Created by Charles Ng on 3/10/2017. 11 | */ 12 | @Module 13 | class SimpleDetailFragmentModule { 14 | @Provides 15 | fun provideVm(simpleDetailFragment: SimpleDetailFragment, 16 | factory: SimpleMasterDetailShareViewModelFactory): SimpleMasterDetailShareViewModel { 17 | return ViewModelProvider(simpleDetailFragment.requireActivity(), 18 | factory) 19 | .get( 20 | SimpleMasterDetailShareViewModel::class.java) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/masterdetail/SimpleListActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.masterdetail 2 | 3 | import androidx.lifecycle.ViewModelProvider 4 | import com.cn29.aac.ui.masterdetail.vm.SimpleMasterDetailShareViewModel 5 | import com.cn29.aac.ui.masterdetail.vm.SimpleMasterDetailShareViewModelFactory 6 | import dagger.Module 7 | import dagger.Provides 8 | 9 | @Module 10 | class SimpleListActivityModule { 11 | @Provides 12 | fun provideVm(simpleListActivity: SimpleListActivity, 13 | factory: SimpleMasterDetailShareViewModelFactory): SimpleMasterDetailShareViewModel { 14 | return ViewModelProvider(simpleListActivity, factory) 15 | .get( 16 | SimpleMasterDetailShareViewModel::class.java) 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/masterdetail/vm/SimpleMasterDetailShareViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.masterdetail.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.cn29.aac.repo.github.GitRepoRepository 6 | import com.cn29.aac.repo.github.Repo 7 | import com.cn29.aac.repo.util.Resource 8 | 9 | /** 10 | * Created by charlesng0209 on 25/6/2017. 11 | */ 12 | class SimpleMasterDetailShareViewModel(private val gitRepoRepository: GitRepoRepository) : 13 | ViewModel() { 14 | fun loadRepos(owner: String?, 15 | name: String?): LiveData> { 16 | return gitRepoRepository.loadRepo(owner, name) 17 | } 18 | 19 | fun loadRepos(owner: String?): LiveData>> { 20 | return gitRepoRepository.loadRepos(owner) 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/masterdetail/vm/SimpleMasterDetailShareViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.masterdetail.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.github.GitRepoRepository 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by Charles Ng on 9/10/2017. 10 | */ 11 | class SimpleMasterDetailShareViewModelFactory @Inject constructor(var gitRepoRepository: GitRepoRepository) : 12 | NewInstanceFactory() { 13 | override fun create(modelClass: Class): T { 14 | return SimpleMasterDetailShareViewModel(gitRepoRepository) as T 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/setting/SettingsActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.setting 2 | 3 | class SettingsActivityModule -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/setting/vm/SettingsActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.setting.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | 5 | /** 6 | * Created by Charles Ng on 13/10/2017. 7 | */ 8 | class SettingsActivityViewModel : 9 | ViewModel() -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/setting/vm/SettingsActivityViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.setting.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import javax.inject.Inject 6 | 7 | /** 8 | * Created by Charles Ng on 13/10/2017. 9 | */ 10 | class SettingsActivityViewModelFactory @Inject constructor() : 11 | NewInstanceFactory() { 12 | override fun create(modelClass: Class): T { 13 | return SettingsActivityViewModel() as T 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/AlbumAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import com.cn29.aac.R 4 | import com.cn29.aac.databinding.ItemAlbumListBinding 5 | import com.cn29.aac.repo.itunes.Album 6 | import com.cn29.aac.ui.common.BaseRecyclerViewAdapter 7 | 8 | 9 | class AlbumAdapter(private val values: List, 10 | albumOnItemClickListener: OnItemClickListener) : 11 | BaseRecyclerViewAdapter( 12 | albumOnItemClickListener) { 13 | override fun getItemForPosition(position: Int): Album { 14 | return values[position] 15 | } 16 | 17 | override fun getLayoutIdForPosition(position: Int): Int { 18 | return R.layout.item_album_list 19 | } 20 | 21 | override fun bind(binding: ItemAlbumListBinding, 22 | item: Album) { 23 | binding.album = item 24 | } 25 | 26 | override fun getItemCount(): Int { 27 | return values.size 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/AlbumFragmentModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.FragmentAlbumBinding 7 | import com.cn29.aac.ui.shopping.vm.AlbumFragmentViewModel 8 | import com.cn29.aac.ui.shopping.vm.AlbumFragmentViewModelFactory 9 | import com.cn29.aac.ui.shopping.vm.ShoppingActivityViewModel 10 | import dagger.Module 11 | import dagger.Provides 12 | 13 | /** 14 | * Created by Charles Ng on 20/10/2017. 15 | */ 16 | @Module 17 | class AlbumFragmentModule { 18 | @Provides 19 | fun getArtistViewModel(factory: AlbumFragmentViewModelFactory, 20 | artistFragment: AlbumFragment): AlbumFragmentViewModel { 21 | return ViewModelProvider(artistFragment.requireActivity(), factory) 22 | .get(AlbumFragmentViewModel::class.java) 23 | } 24 | 25 | @Provides 26 | fun getShoppingKartActivityViewModel(albumFragment: AlbumFragment): ShoppingActivityViewModel { 27 | return ViewModelProvider(albumFragment.requireActivity()) 28 | .get(ShoppingActivityViewModel::class.java) 29 | } 30 | 31 | @Provides 32 | fun provideBinding(artistFragment: AlbumFragment): FragmentAlbumBinding { 33 | return DataBindingUtil 34 | .inflate(artistFragment.requireActivity().layoutInflater, 35 | R.layout.fragment_album, 36 | null, 37 | false) 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/ArtistAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import com.cn29.aac.R 4 | import com.cn29.aac.databinding.ItemArtistGridBinding 5 | import com.cn29.aac.repo.itunes.Artist 6 | import com.cn29.aac.ui.common.BaseRecyclerViewAdapter 7 | 8 | class ArtistAdapter internal constructor(private val mValues: List, 9 | itemClickListener: OnItemClickListener) : 10 | BaseRecyclerViewAdapter( 11 | itemClickListener) { 12 | override fun getItemForPosition(position: Int): Artist { 13 | return mValues[position] 14 | } 15 | 16 | override fun getItemCount(): Int { 17 | return mValues.size 18 | } 19 | 20 | override fun getLayoutIdForPosition(position: Int): Int { 21 | return R.layout.item_artist_grid 22 | } 23 | 24 | override fun bind(binding: ItemArtistGridBinding, 25 | item: Artist) { 26 | binding.artist = item 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/ArtistDetailActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.ActivityArtistDetailBinding 7 | import com.cn29.aac.repo.itunes.Artist 8 | import com.cn29.aac.ui.shopping.vm.ArtistDetailActivityViewModel 9 | import com.cn29.aac.ui.shopping.vm.ArtistDetailActivityViewModelFactory 10 | import dagger.Module 11 | import dagger.Provides 12 | 13 | /** 14 | * Created by Charles Ng on 23/10/2017. 15 | */ 16 | @Module 17 | class ArtistDetailActivityModule { 18 | @Provides 19 | fun provideViewModel(factory: ArtistDetailActivityViewModelFactory, 20 | activity: ArtistDetailActivity): ArtistDetailActivityViewModel { 21 | return ViewModelProvider(activity, factory) 22 | .get( 23 | ArtistDetailActivityViewModel::class.java) 24 | } 25 | 26 | @Provides 27 | fun provideBinding(activity: ArtistDetailActivity): ActivityArtistDetailBinding { 28 | return DataBindingUtil.setContentView(activity, 29 | R.layout.activity_artist_detail) 30 | } 31 | 32 | @Provides 33 | fun provideArtist(activity: ArtistDetailActivity): Artist { 34 | return if (activity.intent.hasExtra("artist")) { 35 | activity.intent.getParcelableExtra("artist") 36 | } else { 37 | Artist() 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/ArtistFragmentModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.FragmentArtistBinding 7 | import com.cn29.aac.ui.shopping.vm.ArtistFragmentViewModel 8 | import com.cn29.aac.ui.shopping.vm.ArtistFragmentViewModelFactory 9 | import com.cn29.aac.ui.shopping.vm.ShoppingActivityViewModel 10 | import dagger.Module 11 | import dagger.Provides 12 | 13 | 14 | @Module 15 | class ArtistFragmentModule { 16 | @Provides 17 | fun getArtistViewModel(factory: ArtistFragmentViewModelFactory, 18 | artistFragment: ArtistFragment): ArtistFragmentViewModel { 19 | return ViewModelProvider(artistFragment.requireActivity(), factory) 20 | .get(ArtistFragmentViewModel::class.java) 21 | } 22 | 23 | @Provides 24 | fun getShoppingKartActivityViewModel(artistFragment: ArtistFragment): ShoppingActivityViewModel { 25 | return ViewModelProvider(artistFragment.requireActivity()) 26 | .get(ShoppingActivityViewModel::class.java) 27 | } 28 | 29 | @Provides 30 | fun provideBinding(artistFragment: ArtistFragment): FragmentArtistBinding { 31 | return DataBindingUtil 32 | .inflate(artistFragment.requireActivity().layoutInflater, 33 | R.layout.fragment_artist, 34 | null, 35 | false) 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/ArtistsSearchRecentSuggestionsProvider.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import android.content.SearchRecentSuggestionsProvider 4 | 5 | 6 | class ArtistsSearchRecentSuggestionsProvider : 7 | SearchRecentSuggestionsProvider() { 8 | companion object { 9 | const val AUTHORITY = "com.cn29.aac.ArtistsSearchRecentSuggestionsProvider" 10 | const val MODE = DATABASE_MODE_QUERIES 11 | } 12 | 13 | init { 14 | setupSuggestions(AUTHORITY, 15 | MODE) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/ShoppingActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.ActivityShoppingBinding 7 | import com.cn29.aac.ui.shopping.vm.ShoppingActivityViewModel 8 | import com.cn29.aac.ui.shopping.vm.ShoppingActivityViewModelFactory 9 | import dagger.Module 10 | import dagger.Provides 11 | 12 | 13 | @Module 14 | class ShoppingActivityModule { 15 | @Provides 16 | fun provideBinding(shoppingActivity: ShoppingActivity): ActivityShoppingBinding { 17 | return DataBindingUtil.setContentView(shoppingActivity, 18 | R.layout.activity_shopping) 19 | } 20 | 21 | @Provides 22 | fun provideVM(factory: ShoppingActivityViewModelFactory, 23 | shoppingActivity: ShoppingActivity): ShoppingActivityViewModel { 24 | return ViewModelProvider(shoppingActivity, factory) 25 | .get(ShoppingActivityViewModel::class.java) 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/AlbumFragmentViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.cn29.aac.datasource.api.ApiResponse 6 | import com.cn29.aac.repo.itunes.Album 7 | import com.cn29.aac.repo.itunes.AlbumSearchResult 8 | import com.cn29.aac.repo.itunes.ItunesRepository 9 | import com.cn29.aac.repo.util.Resource 10 | 11 | /** 12 | * Created by Charles Ng on 20/10/2017. 13 | */ 14 | class AlbumFragmentViewModel(private val itunesRepository: ItunesRepository) : 15 | ViewModel() { 16 | fun getAlbumSearchResult(artistId: Int, 17 | entity: String?): LiveData> { 18 | return itunesRepository.getAlbumSearchResult(artistId, entity) 19 | } 20 | 21 | fun getAlbumResult(artistId: Int, 22 | entity: String?): LiveData>> { 23 | return itunesRepository.getAlbumResult(artistId, entity) 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/AlbumFragmentViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.itunes.ItunesRepository 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by Charles Ng on 20/10/2017. 10 | */ 11 | class AlbumFragmentViewModelFactory @Inject constructor(private val itunesRepository: ItunesRepository) : 12 | NewInstanceFactory() { 13 | override fun create(modelClass: Class): T { 14 | return AlbumFragmentViewModel(itunesRepository) as T 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/ArtistDetailActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | 5 | /** 6 | * Created by Charles Ng on 23/10/2017. 7 | */ 8 | class ArtistDetailActivityViewModel : 9 | ViewModel() -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/ArtistDetailActivityViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import javax.inject.Inject 6 | 7 | /** 8 | * Created by Charles Ng on 23/10/2017. 9 | */ 10 | class ArtistDetailActivityViewModelFactory @Inject constructor() : 11 | NewInstanceFactory() { 12 | override fun create(modelClass: Class): T { 13 | return ArtistDetailActivityViewModel() as T 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/ArtistFragmentViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.cn29.aac.datasource.api.ApiResponse 6 | import com.cn29.aac.repo.itunes.Artist 7 | import com.cn29.aac.repo.itunes.ArtistSearchResult 8 | import com.cn29.aac.repo.itunes.ItunesRepository 9 | import com.cn29.aac.repo.util.Resource 10 | 11 | /** 12 | * Created by Charles Ng on 20/10/2017. 13 | */ 14 | class ArtistFragmentViewModel(private val itunesRepository: ItunesRepository) : 15 | ViewModel() { 16 | fun getArtistSearchResult(term: String?): LiveData> { 17 | return itunesRepository.getArtistSearchResult(term) 18 | } 19 | 20 | fun starArtist(artist: Artist?): Int { 21 | return itunesRepository.starArtist(artist) 22 | } 23 | 24 | fun getArtist(term: String?): LiveData>> { 25 | return itunesRepository.getArtistResult(term) 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/ArtistFragmentViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import com.cn29.aac.repo.itunes.ItunesRepository 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by Charles Ng on 20/10/2017. 10 | */ 11 | class ArtistFragmentViewModelFactory @Inject constructor(private val itunesRepository: ItunesRepository) : 12 | NewInstanceFactory() { 13 | override fun create(modelClass: Class): T { 14 | return ArtistFragmentViewModel(itunesRepository) as T 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/ShoppingActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | /** 8 | * Created by Charles Ng on 23/10/2017. 9 | */ 10 | class ShoppingActivityViewModel : ViewModel() { 11 | private val queryData: MutableLiveData = MutableLiveData() 12 | fun query(query: String) { 13 | queryData.value = query 14 | } 15 | 16 | fun getQueryData(): LiveData { 17 | return queryData 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shopping/vm/ShoppingActivityViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shopping.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import javax.inject.Inject 6 | 7 | /** 8 | * Created by Charles Ng on 23/10/2017. 9 | */ 10 | class ShoppingActivityViewModelFactory @Inject constructor() : 11 | NewInstanceFactory() { 12 | override fun create(modelClass: Class): T { 13 | return ShoppingActivityViewModel() as T 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shoppingkart/ShoppingKartActivity.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shoppingkart 2 | 3 | import android.os.Bundle 4 | import com.cn29.aac.databinding.ActivityShoppingKartBinding 5 | import com.cn29.aac.di.scope.AndroidDataBinding 6 | import com.cn29.aac.di.scope.ViewModel 7 | import com.cn29.aac.ui.base.BaseAppCompatActivity 8 | import com.cn29.aac.ui.shoppingkart.vm.ShoppingKartActivityViewModel 9 | import com.google.android.material.snackbar.Snackbar 10 | import javax.inject.Inject 11 | 12 | class ShoppingKartActivity : BaseAppCompatActivity() { 13 | 14 | @Inject 15 | @ViewModel 16 | lateinit var viewModel: ShoppingKartActivityViewModel 17 | 18 | @Inject 19 | @AndroidDataBinding 20 | lateinit var binding: ActivityShoppingKartBinding 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | setSupportActionBar(binding.toolbar) 24 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 25 | binding.fab.setOnClickListener( 26 | { view -> 27 | Snackbar.make(view, "Replace with your own action", 28 | Snackbar.LENGTH_LONG) 29 | .setAction("Action", null).show() 30 | }) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shoppingkart/ShoppingKartActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shoppingkart 2 | 3 | import androidx.databinding.DataBindingUtil 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.cn29.aac.R 6 | import com.cn29.aac.databinding.ActivityShoppingKartBinding 7 | import com.cn29.aac.ui.shoppingkart.vm.ShoppingKartActivityViewModel 8 | import com.cn29.aac.ui.shoppingkart.vm.ShoppingKartActivityViewModelFactory 9 | import dagger.Module 10 | import dagger.Provides 11 | 12 | @Module 13 | class ShoppingKartActivityModule { 14 | @Provides 15 | fun provideBinding(activity: ShoppingKartActivity): ActivityShoppingKartBinding { 16 | return DataBindingUtil.setContentView(activity, 17 | R.layout.activity_shopping_kart) 18 | } 19 | 20 | @Provides 21 | fun provideVm(factory: ShoppingKartActivityViewModelFactory, 22 | activity: ShoppingKartActivity): ShoppingKartActivityViewModel { 23 | return ViewModelProvider(activity, factory) 24 | .get(ShoppingKartActivityViewModel::class.java) 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shoppingkart/vm/ShoppingKartActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shoppingkart.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | 5 | /** 6 | * Created by Charles Ng on 25/10/2017. 7 | */ 8 | class ShoppingKartActivityViewModel : 9 | ViewModel() -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/shoppingkart/vm/ShoppingKartActivityViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.shoppingkart.vm 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.ViewModelProvider.NewInstanceFactory 5 | import javax.inject.Inject 6 | 7 | /** 8 | * Created by Charles Ng on 25/10/2017. 9 | */ 10 | class ShoppingKartActivityViewModelFactory @Inject constructor() : 11 | NewInstanceFactory() { 12 | override fun create(modelClass: Class): T { 13 | return ShoppingKartActivityViewModel() as T 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/viewpager/BlankFragmentAModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.viewpager 2 | 3 | import androidx.lifecycle.ViewModelProvider 4 | import com.cn29.aac.ui.viewpager.vm.PagerAgentViewModel 5 | import dagger.Module 6 | import dagger.Provides 7 | 8 | 9 | @Module 10 | class BlankFragmentAModule { 11 | @Provides 12 | fun providePagerAgentVm(blankFragmentA: BlankFragmentA): PagerAgentViewModel { 13 | return ViewModelProvider(blankFragmentA.requireActivity()) 14 | .get(PagerAgentViewModel::class.java) 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/viewpager/BlankFragmentBModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.viewpager 2 | 3 | import androidx.lifecycle.ViewModelProvider 4 | import com.cn29.aac.ui.viewpager.vm.PagerAgentViewModel 5 | import dagger.Module 6 | import dagger.Provides 7 | 8 | @Module 9 | class BlankFragmentBModule { 10 | @Provides 11 | fun providePagerAgentVm(blankFragmentB: BlankFragmentB): PagerAgentViewModel { 12 | return ViewModelProvider(blankFragmentB.requireActivity()) 13 | .get(PagerAgentViewModel::class.java) 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/viewpager/PagerActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.viewpager 2 | 3 | import androidx.lifecycle.ViewModelProvider 4 | import com.cn29.aac.ui.viewpager.vm.PagerAgentViewModel 5 | import dagger.Module 6 | import dagger.Provides 7 | 8 | @Module 9 | class PagerActivityModule { 10 | @Provides 11 | fun providePagerAgentVm(pagerActivity: PagerActivity): PagerAgentViewModel { 12 | return ViewModelProvider(pagerActivity) 13 | .get(PagerAgentViewModel::class.java) 14 | .also { 15 | it.init() 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/cn29/aac/ui/viewpager/vm/PagerAgentViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.cn29.aac.ui.viewpager.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | /** 8 | * Created by charlesng0209 on 19/6/2017. 9 | */ 10 | class PagerAgentViewModel : ViewModel() { 11 | private var messageContainerA: MutableLiveData? = null 12 | private var messageContainerB: MutableLiveData? = null 13 | fun init() { 14 | messageContainerA = MutableLiveData() 15 | messageContainerA?.value = "Default Message" 16 | messageContainerB = MutableLiveData() 17 | messageContainerB?.value = "Default Message" 18 | } 19 | 20 | fun sendMessageToB(msg: String) { 21 | messageContainerB?.value = msg 22 | } 23 | 24 | fun sendMessageToA(msg: String) { 25 | messageContainerA?.value = msg 26 | } 27 | 28 | fun getMessageContainerA(): LiveData? { 29 | return messageContainerA 30 | } 31 | 32 | fun getMessageContainerB(): LiveData? { 33 | return messageContainerB 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_add_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_add_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_add_shopping_cart_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_add_shopping_cart_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_album_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_album_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_exit_to_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_exit_to_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_exit_to_app_grey_700_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_exit_to_app_grey_700_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_favorite_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_favorite_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_history_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_history_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_mode_edit_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_mode_edit_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_people_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_people_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_reorder_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_reorder_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_search_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_search_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-hdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_add_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_add_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_add_shopping_cart_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_add_shopping_cart_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_album_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_album_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_exit_to_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_exit_to_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_exit_to_app_grey_700_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_exit_to_app_grey_700_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_favorite_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_favorite_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_history_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_history_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_mode_edit_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_mode_edit_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_people_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_people_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_reorder_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_reorder_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_search_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_search_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-mdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_gallery.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_manage.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_slideshow.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_add_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_add_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_add_shopping_cart_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_add_shopping_cart_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_album_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_album_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_exit_to_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_exit_to_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_exit_to_app_grey_700_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_exit_to_app_grey_700_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_favorite_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_favorite_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_history_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_history_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_mode_edit_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_mode_edit_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_people_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_people_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_reorder_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_reorder_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_search_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_search_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xhdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_add_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_add_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_add_shopping_cart_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_add_shopping_cart_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_album_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_album_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_exit_to_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_exit_to_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_exit_to_app_grey_700_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_exit_to_app_grey_700_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_favorite_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_favorite_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_history_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_history_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_mode_edit_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_mode_edit_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_people_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_people_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_reorder_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_reorder_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxhdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_add_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_add_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_add_shopping_cart_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_add_shopping_cart_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_album_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_album_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_grey_700_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_grey_700_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_favorite_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_favorite_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_history_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_history_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_mode_edit_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_people_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_people_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_reorder_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_reorder_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_shopping_cart_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_shopping_cart_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/drawable-xxxhdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sync_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout-w900dp/fragment_simple_list.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | 20 | 31 | 32 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_app_arch_navigation_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 14 | 15 | 19 | 20 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_location.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_shopping_kart.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_simple_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 33 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_bar_app_arch_navigation_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_app_arch_navigation_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_artist_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_location.xml: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_shopping_kart.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_album.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_artist.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_blank_a.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 19 | 20 |