├── .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 |
4 |
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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/statistic.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
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 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_blank_b.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
19 |
20 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_feedentry_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_simple_detail.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_simple_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_simple_list_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_artist_grid.xml:
--------------------------------------------------------------------------------
1 |
16 |
19 |
20 |
23 |
24 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_app_arch_navigation_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
21 |
22 |
28 |
29 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/progress_dialog.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/app_arch_navigation_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_artist_card.xml:
--------------------------------------------------------------------------------
1 |
5 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_artist_detail.xml:
--------------------------------------------------------------------------------
1 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_feed.xml:
--------------------------------------------------------------------------------
1 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_feed_entry_detail.xml:
--------------------------------------------------------------------------------
1 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_feed_item_card.xml:
--------------------------------------------------------------------------------
1 |
5 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/options_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #FFFFFF
7 | #424242
8 | #9E9E9E
9 | #757575
10 | #f7cb2a
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 350dp
7 | 200dp
8 | 16dp
9 | 8dp
10 | 176dp
11 | 304dp
12 | 16dp
13 | 8dp
14 | 160dp
15 | 72dp
16 | 40dp
17 | 40dp
18 | 20sp
19 | 48dp
20 | 48dp
21 | 16sp
22 | 200dp
23 | 14sp
24 | 222dp
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_camera
3 | - @android:drawable/ic_menu_gallery
4 | - @android:drawable/ic_menu_slideshow
5 | - @android:drawable/ic_menu_manage
6 | - @android:drawable/ic_menu_share
7 | - @android:drawable/ic_menu_send
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_data_sync.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
20 |
21 |
23 |
24 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_headers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_notification.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/searchable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/api/LiveDataCallAdapterFactoryTest.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.api
2 |
3 | internal class LiveDataCallAdapterFactoryTest
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/api/LiveDataCallAdapterTest.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.api
2 |
3 | import org.junit.jupiter.api.Test
4 |
5 | internal class LiveDataCallAdapterTest {
6 |
7 | @Test
8 | fun responseType() {
9 | }
10 |
11 | @Test
12 | fun adapt() {
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/api/MockItunesService.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.api
2 |
3 |
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/auth/remote/FacebookAuthTest.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.auth.remote
2 |
3 | import com.cn29.aac.utils.InstantExecutorExtension
4 | import org.junit.jupiter.api.Assertions.assertEquals
5 | import org.junit.jupiter.api.BeforeEach
6 | import org.junit.jupiter.api.Test
7 | import org.junit.jupiter.api.extension.ExtendWith
8 |
9 | @ExtendWith(InstantExecutorExtension::class)
10 | class FacebookAuthTest {
11 | private lateinit var faceBookAuth: FacebookAuth
12 |
13 | @BeforeEach
14 | internal fun setUp() {
15 | faceBookAuth = FacebookAuth()
16 | }
17 |
18 | @Test
19 | fun `should set login status as 1 and authtype as facebook`() {
20 | val email = "charlesng0209@gmail.com"
21 | val liveData = faceBookAuth.getLogin(email)
22 | assertEquals(1, liveData.value?.body?.isLogin)
23 | assertEquals("Facebook", liveData.value?.body?.authType)
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/auth/remote/GoogleAuthTest.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.auth.remote
2 |
3 | import com.cn29.aac.utils.InstantExecutorExtension
4 | import org.junit.jupiter.api.Assertions.assertEquals
5 | import org.junit.jupiter.api.BeforeEach
6 | import org.junit.jupiter.api.Test
7 | import org.junit.jupiter.api.extension.ExtendWith
8 |
9 | @ExtendWith(InstantExecutorExtension::class)
10 | class GoogleAuthTest {
11 | private lateinit var googleAuth: GoogleAuth
12 |
13 | @BeforeEach
14 | internal fun setUp() {
15 | googleAuth = GoogleAuth()
16 | }
17 |
18 | @Test
19 | fun `should set login status as 1 and authtype as google`() {
20 | val email = "charlesng0209@gmail.com"
21 | val liveData = googleAuth.getLogin(email)
22 | assertEquals(1, liveData.value?.body?.isLogin)
23 | assertEquals("Google", liveData.value?.body?.authType)
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/auth/remote/MyCompanyAuthTest.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.auth.remote
2 |
3 | import com.cn29.aac.utils.InstantExecutorExtension
4 | import org.junit.jupiter.api.Assertions.assertEquals
5 | import org.junit.jupiter.api.BeforeEach
6 | import org.junit.jupiter.api.Test
7 | import org.junit.jupiter.api.extension.ExtendWith
8 |
9 | @ExtendWith(InstantExecutorExtension::class)
10 | internal class MyCompanyAuthTest {
11 |
12 | private lateinit var myCompanyAuth: MyCompanyAuth
13 |
14 | @BeforeEach
15 | fun setUp() {
16 | myCompanyAuth = MyCompanyAuth()
17 | }
18 |
19 | @Test
20 | fun `should set login status as 1 and authtype as MyCompany`() {
21 | val liveData = myCompanyAuth.getLogin("charlesng0209@gmail.com")
22 | assertEquals(1, liveData.value?.body?.isLogin)
23 | assertEquals("MyCompany", liveData.value?.body?.authType)
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/datasource/github/remote/GithubTypeConvertersTest.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.datasource.github.remote
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 |
6 | internal class GithubTypeConvertersTest {
7 | private lateinit var converter: GithubTypeConverters
8 |
9 | @Test
10 | fun `should return (1,2) if the string is "1,2"`() {
11 | val listIds = GithubTypeConverters.stringToIntList("1,2")
12 | assertEquals(listOf(1, 2), listIds)
13 | }
14 |
15 | @Test
16 | fun `should return empty list if the string is empty`() {
17 | val listIds = GithubTypeConverters.stringToIntList("")
18 | assertEquals(emptyList(), listIds)
19 | }
20 |
21 | @Test
22 | fun `should return string 1,2 if the list is (1,2)`() {
23 | val str = GithubTypeConverters.intListToString(listOf(1, 2))
24 | assertEquals("1,2", str)
25 | }
26 |
27 | @Test
28 | fun `should return empty string if the list is empty`() {
29 | val str = GithubTypeConverters.intListToString(emptyList())
30 | assertEquals("", str)
31 | }
32 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/cn29/aac/utils/InstantExecutorExtension.kt:
--------------------------------------------------------------------------------
1 | package com.cn29.aac.utils
2 |
3 | import androidx.arch.core.executor.ArchTaskExecutor
4 | import androidx.arch.core.executor.TaskExecutor
5 | import org.junit.jupiter.api.extension.AfterEachCallback
6 | import org.junit.jupiter.api.extension.BeforeEachCallback
7 | import org.junit.jupiter.api.extension.ExtensionContext
8 |
9 | class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback {
10 |
11 | override fun beforeEach(context: ExtensionContext?) {
12 | ArchTaskExecutor.getInstance()
13 | .setDelegate(object : TaskExecutor() {
14 | override fun executeOnDiskIO(runnable: Runnable) = runnable.run()
15 |
16 | override fun postToMainThread(runnable: Runnable) = runnable.run()
17 |
18 | override fun isMainThread(): Boolean = true
19 | })
20 | }
21 |
22 | override fun afterEach(context: ExtensionContext?) {
23 | ArchTaskExecutor.getInstance().setDelegate(null)
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/app/src/test/resources/abc.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/app/src/test/resources/abc.txt
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 |
4 |
5 | ext.junit5_version = "5.5.2"
6 | ext.room_version = "2.2.4"
7 | ext.lifecycle_version = "2.2.0"
8 | ext.arch_version = "1.1.1"
9 | ext.support_version = "28.0.0"
10 | ext.constraint_layout_version = "1.0.2"
11 | ext.junit_version = "4.12"
12 | ext.dagger2_version = "2.16"
13 | ext.retrofit_version="2.8.0"
14 | ext.picasso_version="2.5.2"
15 |
16 | buildscript {
17 | ext.kotlin_version = '1.3.71'
18 | repositories {
19 | jcenter()
20 | google()
21 | }
22 | dependencies {
23 | classpath 'com.android.tools.build:gradle:3.6.1'
24 | classpath 'com.google.gms:google-services:4.3.3'
25 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
26 | classpath "de.mannodermaus.gradle.plugins:android-junit5:1.5.2.0"
27 | classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4'
28 | }
29 | }
30 |
31 | allprojects {
32 | repositories {
33 | jcenter()
34 | google()
35 | }
36 | }
37 |
38 | task clean(type: Delete) {
39 | delete rootProject.buildDir
40 | }
41 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Mon Sep 04 17:53:37 CST 2017
16 | systemProp.http.proxyHost=
17 | org.gradle.jvmargs=-Xmx1536m
18 | systemProp.http.proxyPort=80
19 | android.useAndroidX=true
20 | android.enableJetifier=true
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Mar 05 23:27:59 CET 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
--------------------------------------------------------------------------------
/init.sh:
--------------------------------------------------------------------------------
1 | cp prepare-commit-msg.sample .git/hooks/prepare-commit-msg
2 | chmod +x .git/hooks/prepare-commit-msg
--------------------------------------------------------------------------------
/markdown/img/feed_entry_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/feed_entry_1.png
--------------------------------------------------------------------------------
/markdown/img/feed_entry_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/feed_entry_2.png
--------------------------------------------------------------------------------
/markdown/img/feed_entry_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/feed_entry_3.png
--------------------------------------------------------------------------------
/markdown/img/feed_entry_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/feed_entry_4.png
--------------------------------------------------------------------------------
/markdown/img/fragment_communication_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/fragment_communication_1.png
--------------------------------------------------------------------------------
/markdown/img/fragment_communication_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/fragment_communication_2.png
--------------------------------------------------------------------------------
/markdown/img/fragment_communication_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/fragment_communication_3.png
--------------------------------------------------------------------------------
/markdown/img/location_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/location_1.png
--------------------------------------------------------------------------------
/markdown/img/master_detail_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/master_detail_1.png
--------------------------------------------------------------------------------
/markdown/img/master_detail_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/master_detail_2.png
--------------------------------------------------------------------------------
/markdown/img/master_detail_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/master_detail_3.png
--------------------------------------------------------------------------------
/markdown/img/view_pager_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/view_pager_1.png
--------------------------------------------------------------------------------
/markdown/img/view_pager_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charlesng/SampleAppArch/8aed2841f945d704b2c4898cd23ead2d2fb53eb0/markdown/img/view_pager_2.png
--------------------------------------------------------------------------------
/markdown/itunes_api.md:
--------------------------------------------------------------------------------
1 | Use the API from
2 |
3 | https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/iTuneSearchAPI/LookupExamples.html
4 |
--------------------------------------------------------------------------------
/markdown/location.md:
--------------------------------------------------------------------------------
1 | # Location
2 |
3 |
4 | Sample from
5 | https://developer.android.com/training/location/retrieve-current.html
6 | https://developer.android.com/topic/libraries/architecture/lifecycle.html
7 |
8 | # MyLocationListener
9 | - From the example in https://developer.android.com/topic/libraries/architecture/lifecycle.html
10 |
11 | # LocationActivity
12 | - Use 2-way Android databinding to show the real time location
13 | - Use LiveData to observer the real time location data and show it on UI
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/markdown/masterdetail.md:
--------------------------------------------------------------------------------
1 | # Communication-Fragments
2 |
3 | # Sample from Android Developer :
4 | - Master Detail Template (From Android Studio Gallery)
5 | - android.v4.ViewPager
6 |
7 |
8 |
9 |
10 | # Master Detail Template
11 | - Use the template import first and modified the template to fit Android App Architecture
12 | - https://stackoverflow.com/questions/44272914/sharing-data-between-fragments-using-new-architecture-component-viewmodel/44655954#44655954
13 | - Main Points :
14 | - Small Device (MasterFragment -> DetailFragment by ShareViewModel)
15 | - Large Device (ListActivity -> DetailActivity by putExtra method)
16 | - To keep it to the same codebase, we need to defined both ShareViewModel in ListActivity and DetailActivity. However, the value setting in DetailActivity will use putExtra method to transfer data
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/markdown/viewpager.md:
--------------------------------------------------------------------------------
1 | # Communication-Fragments
2 |
3 | # Sample from Android Developer :
4 | - Master Detail Template (From Android Studio Gallery)
5 | - android.v4.ViewPager
6 |
7 |
8 |
9 |
10 |
11 | # ViewPager
12 | - https://stackoverflow.com/questions/44272914/sharing-data-between-fragments-using-new-architecture-component-viewmodel/44655954#44655954
13 | - Fragment A and Fragment B send simple text to each other
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/prepare-commit-msg.sample:
--------------------------------------------------------------------------------
1 | # Reference :https://medium.com/better-programming/how-to-automatically-add-the-ticket-number-in-git-commit-message-bda5426ded05
2 | # Reference :https://gist.github.com/bartoszmajsak/1396344
3 |
4 | #!/bin/bash
5 | FILE=$1
6 | MESSAGE=$(cat $FILE)
7 | #BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
8 | TICKET=[$(git rev-parse --abbrev-ref HEAD | grep -Eo '^(\w+/)?(\w+[-_])?[0-9]+' | grep -Eo '(\w+[-])?[0-9]+' | tr "[:lower:]" "[:upper:]")]
9 | if [[ $TICKET == "[]" || "$MESSAGE" == "$TICKET"* ]];then
10 | exit 0;
11 | fi
12 |
13 | echo "$TICKET $MESSAGE" > $FILE
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------