├── user ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── user_ic_launcher.xml │ │ │ │ └── user_ic_launcher_round.xml │ │ │ └── layout │ │ │ │ └── user_activity_main.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── user │ │ │ │ ├── bridge │ │ │ │ └── UserBridge.kt │ │ │ │ ├── repository │ │ │ │ └── UserRepository.kt │ │ │ │ ├── UserMainActivity.kt │ │ │ │ └── vm │ │ │ │ └── UserInfoVM.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── user │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── user │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── app ├── .gitignore ├── keystore ├── src │ ├── main │ │ ├── res │ │ │ ├── drawable │ │ │ │ ├── back.png │ │ │ │ ├── app_welcome.png │ │ │ │ ├── github_icon.jpg │ │ │ │ ├── home_default.png │ │ │ │ ├── home_selected.png │ │ │ │ ├── notification.png │ │ │ │ ├── user_default.png │ │ │ │ ├── user_selected.png │ │ │ │ ├── search_default.png │ │ │ │ ├── search_selected.png │ │ │ │ ├── repository_default.png │ │ │ │ ├── notification_default.png │ │ │ │ ├── repository_selected.png │ │ │ │ ├── notification_selected.png │ │ │ │ ├── bg_8bc34a_radius_5.xml │ │ │ │ ├── bg_00bcd4_radius_5.xml │ │ │ │ ├── bg_03a9f4_radius_5.xml │ │ │ │ ├── bg_4caf50_radius_5.xml │ │ │ │ ├── bg_8bc34a_transparent_30_radius_5.xml │ │ │ │ ├── bg_selector_home.xml │ │ │ │ ├── bg_selector_user.xml │ │ │ │ ├── bg_selector_authorize.xml │ │ │ │ ├── bg_selector_repository.xml │ │ │ │ └── bg_selector_sign_in.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 │ │ │ │ ├── dimens.xml │ │ │ │ ├── attrs.xml │ │ │ │ ├── styles.xml │ │ │ │ └── strings.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── color │ │ │ │ └── bottom_navigation_selector.xml │ │ │ ├── layout │ │ │ │ ├── activity_welcome.xml │ │ │ │ └── include_welcome.xml │ │ │ └── menu │ │ │ │ └── main_menu.xml │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── github │ │ │ ├── FakeCrashLibrary.kt │ │ │ ├── startup │ │ │ ├── AwesomeGithubStartupConfig.kt │ │ │ ├── UtilsStartup.kt │ │ │ └── AsyncBridgeStartup.kt │ │ │ ├── bridge │ │ │ └── AppBridge.kt │ │ │ ├── widget │ │ │ └── NonScrollViewPager.kt │ │ │ └── ui │ │ │ ├── main │ │ │ └── MainViewPagerAdapter.kt │ │ │ └── welcome │ │ │ └── WelcomeVM.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── awesome │ │ │ └── github │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── awesome │ │ └── github │ │ └── ExampleInstrumentedTest.kt ├── release │ └── output.json └── proguard-rules.pro ├── basic ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── basic │ │ │ ├── repository │ │ │ └── BaseRepository.kt │ │ │ ├── BaseRecyclerVM.kt │ │ │ ├── BaseVM.kt │ │ │ └── recyclerview │ │ │ ├── CommonRecyclerViewVH.kt │ │ │ └── BasePagedListAdapter.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── basic │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── basic │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── common ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── attrs.xml │ │ │ │ ├── colors.xml │ │ │ │ └── dimens.xml │ │ │ ├── drawable-nodpi │ │ │ │ ├── back.png │ │ │ │ ├── circle.png │ │ │ │ ├── start.png │ │ │ │ ├── license.png │ │ │ │ ├── loading.gif │ │ │ │ ├── notification.png │ │ │ │ ├── placeholder.jpeg │ │ │ │ └── git_repo_forked.png │ │ │ ├── drawable-xxhdpi │ │ │ │ ├── issue_open.png │ │ │ │ ├── issue_closed.png │ │ │ │ └── pull_request.png │ │ │ └── drawable │ │ │ │ └── corners_2_solid_white_stroke_1_darker_gray_bg.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── common │ │ │ ├── model │ │ │ ├── BaseRecyclerViewModel.kt │ │ │ ├── SearchModel.kt │ │ │ ├── FollowersModel.kt │ │ │ ├── ResultModel.kt │ │ │ ├── NotificationModel.kt │ │ │ ├── ResponseModel.kt │ │ │ └── ReposModel.kt │ │ │ ├── navigation │ │ │ ├── OnNavigationListener.kt │ │ │ └── OnNavigationListenerImpl.kt │ │ │ ├── ToPageStatus.kt │ │ │ ├── Constants.kt │ │ │ ├── ARouterPaths.kt │ │ │ ├── utils │ │ │ └── LoadingUtils.kt │ │ │ ├── extensions │ │ │ ├── CommonExtensions.kt │ │ │ └── HttpExtensions.kt │ │ │ └── custom │ │ │ └── LoadingView.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── common │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── common │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── followers ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ └── mipmap-anydpi-v26 │ │ │ │ ├── followers_ic_launcher.xml │ │ │ │ └── followers_ic_launcher_round.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── followers │ │ │ │ ├── bridge │ │ │ │ └── FollowersBridge.kt │ │ │ │ ├── repository │ │ │ │ └── FollowersRepository.kt │ │ │ │ ├── vm │ │ │ │ └── FollowersVHVM.kt │ │ │ │ ├── FollowersActivity.kt │ │ │ │ ├── adapter │ │ │ │ └── FollowersAdapter.kt │ │ │ │ └── FollowersApp.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── followers │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── followers │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── following ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ └── mipmap-anydpi-v26 │ │ │ │ ├── following_ic_launcher.xml │ │ │ │ └── following_ic_launcher_round.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── following │ │ │ │ ├── bridge │ │ │ │ └── FollowingBridge.kt │ │ │ │ ├── repository │ │ │ │ └── FollowingRepository.kt │ │ │ │ ├── vm │ │ │ │ └── FollowingVHVM.kt │ │ │ │ ├── FollowingActivity.kt │ │ │ │ ├── adapter │ │ │ │ └── FollowingAdapter.kt │ │ │ │ └── FollowingApp.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── following │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── following │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── home ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── 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 │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── home_ic_launcher.xml │ │ │ │ └── home_ic_launcher_round.xml │ │ │ └── layout │ │ │ │ └── home_activity_main.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── home │ │ │ │ ├── fragment │ │ │ │ ├── vm │ │ │ │ │ └── HomeUserInfoVM.kt │ │ │ │ ├── repository │ │ │ │ │ └── HomeRepository.kt │ │ │ │ ├── HomeFragment.kt │ │ │ │ └── adapter │ │ │ │ │ └── HomePagedListAdapter.kt │ │ │ │ ├── bridge │ │ │ │ └── HomeBridge.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ └── HomeApp.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── home │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── home │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── login ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── drawable │ │ │ │ ├── app_welcome.png │ │ │ │ ├── login_bg_8bc34a_radius_5.xml │ │ │ │ ├── login_bg_00bcd4_radius_5.xml │ │ │ │ ├── login_bg_03a9f4_radius_5.xml │ │ │ │ ├── login_bg_4caf50_radius_5.xml │ │ │ │ ├── login_bg_8bc34a_transparent_30_radius_5.xml │ │ │ │ ├── login_bg_selector_authorize.xml │ │ │ │ └── login_bg_selector_sign_in.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 │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── login_ic_launcher.xml │ │ │ │ └── login_ic_launcher_round.xml │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── styles.xml │ │ │ │ └── colors.xml │ │ │ └── layout │ │ │ │ └── login_activity_main.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── login │ │ │ │ ├── RequestModel.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ └── LoginApp.kt │ │ ├── AndroidManifest.xml │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── login │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── login │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── repos ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ └── mipmap-anydpi-v26 │ │ │ │ ├── repos_ic_launcher.xml │ │ │ │ └── repos_ic_launcher_round.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── repos │ │ │ │ ├── bridge │ │ │ │ └── ReposBridge.kt │ │ │ │ ├── repository │ │ │ │ └── ReposRepository.kt │ │ │ │ ├── ReposActivity.kt │ │ │ │ ├── ReposApp.kt │ │ │ │ ├── adapter │ │ │ │ └── ReposAdapter.kt │ │ │ │ └── vm │ │ │ │ └── ReposVHVM.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── repos │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── example │ │ └── repos │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── search ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── search_ic_launcher.xml │ │ │ │ └── search_ic_launcher_round.xml │ │ │ └── layout │ │ │ │ └── search_activity_main_layout.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── search │ │ │ │ ├── bridge │ │ │ │ └── SearchBridge.kt │ │ │ │ ├── repository │ │ │ │ └── SearchRepository.kt │ │ │ │ ├── fragment │ │ │ │ └── SearchFragment.kt │ │ │ │ ├── SearchMainActivity.kt │ │ │ │ └── SearchApp.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── search │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── search │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── webview ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── webview_ic_launcher.xml │ │ │ │ └── webview_ic_launcher_round.xml │ │ │ └── layout │ │ │ │ ├── webview_activity_webview_main.xml │ │ │ │ └── webview_activity_webview.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── webview │ │ │ │ ├── bridge │ │ │ │ └── WebViewBridge.kt │ │ │ │ ├── repository │ │ │ │ └── WebViewRepository.kt │ │ │ │ ├── WebViewApp.kt │ │ │ │ ├── WebViewMainActivity.kt │ │ │ │ └── vm │ │ │ │ └── WebViewMainVM.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── webview │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── webview │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── network ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── network │ │ │ └── GithubApiInterceptor.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── awesome │ │ │ └── network │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── awesome │ │ └── network │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── notification ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── notify_ic_launcher.xml │ │ │ │ └── notify_ic_launcher_round.xml │ │ │ └── layout │ │ │ │ └── notify_activity_main_layout.xml │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── idisfkj │ │ │ │ └── awesome │ │ │ │ └── notification │ │ │ │ ├── bridge │ │ │ │ └── NotificationBridge.kt │ │ │ │ ├── NotificationMainActivity.kt │ │ │ │ ├── fragment │ │ │ │ └── NotificationFragment.kt │ │ │ │ ├── NotificationApp.kt │ │ │ │ └── adapter │ │ │ │ └── NotificationAdapter.kt │ │ └── manifest │ │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── notification │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── notification │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── componentbridge ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── componentbridge │ │ │ ├── BridgeInterface.kt │ │ │ ├── factory │ │ │ ├── Factory.kt │ │ │ └── NewInstanceFactory.kt │ │ │ ├── user │ │ │ ├── DefaultUserBridge.kt │ │ │ └── UserBridgeInterface.kt │ │ │ ├── home │ │ │ ├── DefaultHomeBridge.kt │ │ │ └── HomeBridgeInterface.kt │ │ │ ├── search │ │ │ ├── DefaultSearchBridge.kt │ │ │ └── SearchBridgeInterface.kt │ │ │ ├── notification │ │ │ ├── DefaultNotificationBridge.kt │ │ │ └── NotificationBridgeInterface.kt │ │ │ ├── following │ │ │ ├── FollowingBridgeInterface.kt │ │ │ └── DefaultFollowingBridge.kt │ │ │ ├── followers │ │ │ ├── FollowersBridgeInterface.kt │ │ │ └── DefaultFollowersBridge.kt │ │ │ ├── webview │ │ │ ├── WebViewBridgeInterface.kt │ │ │ └── DefaultWebViewBridge.kt │ │ │ ├── repos │ │ │ ├── ReposBridgeInterface.kt │ │ │ └── DefaultReposBridge.kt │ │ │ ├── app │ │ │ ├── AppBridgeInterface.kt │ │ │ └── DefaultAppBridge.kt │ │ │ ├── store │ │ │ └── BridgeStore.kt │ │ │ └── provider │ │ │ └── BridgeProvider.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── idisfkj │ │ │ └── awesome │ │ │ └── componentbridge │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── idisfkj │ │ └── awesome │ │ └── componentbridge │ │ └── ExampleInstrumentedTest.java └── proguard-rules.pro ├── keystore.properties ├── images └── awesome_github.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitignore └── gradle.properties /user/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /basic/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /common/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /followers/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /following/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /home/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /login/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /repos/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /repos/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /search/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /user/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /webview/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /followers/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /following/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /network/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /notification/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /webview/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /componentbridge/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /notification/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/keystore -------------------------------------------------------------------------------- /keystore.properties: -------------------------------------------------------------------------------- 1 | storePassword = awesomegithub 2 | keyPassword = awesomegithub -------------------------------------------------------------------------------- /images/awesome_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/images/awesome_github.png -------------------------------------------------------------------------------- /basic/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Basic 3 | 4 | -------------------------------------------------------------------------------- /common/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Common 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /network/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Network 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/back.png -------------------------------------------------------------------------------- /search/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Search 3 | 4 | -------------------------------------------------------------------------------- /webview/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | WebView 3 | 4 | -------------------------------------------------------------------------------- /componentbridge/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ComponentBridage 3 | 4 | -------------------------------------------------------------------------------- /followers/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Followers 3 | 4 | -------------------------------------------------------------------------------- /following/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Following 3 | 4 | -------------------------------------------------------------------------------- /notification/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Notification 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/app_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/app_welcome.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/github_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/github_icon.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/home_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/home_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/home_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/home_selected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/notification.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/user_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/user_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/user_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/user_selected.png -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/back.png -------------------------------------------------------------------------------- /login/src/main/res/drawable/app_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/drawable/app_welcome.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/search_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/search_selected.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/circle.png -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/start.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/repository_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/repository_default.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 55dp 4 | -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/license.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/license.png -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/loading.gif -------------------------------------------------------------------------------- /home/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/notification_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/notification_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/repository_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/repository_selected.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /basic/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /common/src/main/res/drawable-xxhdpi/issue_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-xxhdpi/issue_open.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /user/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/notification_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/drawable/notification_selected.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/notification.png -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/placeholder.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/placeholder.jpeg -------------------------------------------------------------------------------- /common/src/main/res/drawable-xxhdpi/issue_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-xxhdpi/issue_closed.png -------------------------------------------------------------------------------- /common/src/main/res/drawable-xxhdpi/pull_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-xxhdpi/pull_request.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /search/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /common/src/main/res/drawable-nodpi/git_repo_forked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/common/src/main/res/drawable-nodpi/git_repo_forked.png -------------------------------------------------------------------------------- /home/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/home/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /login/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idisfkj/AwesomeGithub/HEAD/login/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /network/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /notification/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /componentbridge/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /repos/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Repository 3 | private 4 | 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':network', ':common', ':componentbridge', ':basic', ':login', ':home', ':user', ':repos', ':followers', ':following', ':notification', ':search', ':webview' 2 | -------------------------------------------------------------------------------- /home/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_8bc34a_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_00bcd4_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_03a9f4_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_4caf50_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/BaseRecyclerViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-09-03. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | open class BaseRecyclerViewModel(var itemType: Int = 0) 8 | -------------------------------------------------------------------------------- /home/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_8bc34a_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /repos/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /user/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_00bcd4_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_03a9f4_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_4caf50_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /search/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /notification/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /webview/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_8bc34a_transparent_30_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Aug 12 14:45:37 CST 2019 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.1.1-all.zip 7 | -------------------------------------------------------------------------------- /followers/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /following/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_8bc34a_transparent_30_radius_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/BridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge 2 | 3 | /** 4 | * component bridge interface 5 | * Created by idisfkj on 2019-08-29. 6 | * Email : idisfkj@gmail.com. 7 | */ 8 | interface BridgeInterface { 9 | 10 | fun onClear() {} 11 | } -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/color/bottom_navigation_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /basic/src/main/java/com/idisfkj/awesome/basic/repository/BaseRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic.repository 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | 5 | /** 6 | * Created by idisfkj on 2019-08-30. 7 | * Email : idisfkj@gmail.com. 8 | */ 9 | abstract class BaseRepository(var scope: CoroutineScope) 10 | 11 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/navigation/OnNavigationListener.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.navigation 2 | 3 | /** 4 | * Created by idisfkj on 2019-08-29. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | interface OnNavigationListener { 8 | 9 | fun onBackClick() 10 | 11 | fun onRightIconClick() 12 | } 13 | -------------------------------------------------------------------------------- /home/src/main/res/mipmap-anydpi-v26/home_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /login/src/main/res/mipmap-anydpi-v26/login_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /repos/src/main/res/mipmap-anydpi-v26/repos_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /user/src/main/res/mipmap-anydpi-v26/user_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selector_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selector_user.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/SearchModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-12-02. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | data class SearchModel( 8 | val total_count: Int, 9 | val incomplete_results: Boolean, 10 | val items: List 11 | ) 12 | -------------------------------------------------------------------------------- /home/src/main/res/mipmap-anydpi-v26/home_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /search/src/main/res/mipmap-anydpi-v26/search_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /user/src/main/res/mipmap-anydpi-v26/user_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /login/src/main/res/mipmap-anydpi-v26/login_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /notification/src/main/res/mipmap-anydpi-v26/notify_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /repos/src/main/res/mipmap-anydpi-v26/repos_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /search/src/main/res/mipmap-anydpi-v26/search_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /webview/src/main/res/mipmap-anydpi-v26/webview_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selector_authorize.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/FollowersModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-11-22. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | data class FollowersModel( 8 | val login: String, 9 | val avatar_url: String, 10 | val html_url: String 11 | ) : BaseRecyclerViewModel() -------------------------------------------------------------------------------- /webview/src/main/res/mipmap-anydpi-v26/webview_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /followers/src/main/res/mipmap-anydpi-v26/followers_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /following/src/main/res/mipmap-anydpi-v26/following_ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /notification/src/main/res/mipmap-anydpi-v26/notify_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selector_repository.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /followers/src/main/res/mipmap-anydpi-v26/followers_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /following/src/main/res/mipmap-anydpi-v26/following_ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /repos/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/ResultModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-12-11. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | sealed class ResponseResult 8 | 9 | data class ResponseSuccess(val data: T?) : ResponseResult() 10 | data class ResponseError(val t: Throwable?) : ResponseResult() -------------------------------------------------------------------------------- /webview/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_selector_authorize.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /user/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | User 3 | user avatar 4 | Repos 5 | Gists 6 | Followers 7 | Following 8 | 9 | -------------------------------------------------------------------------------- /followers/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /following/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/FakeCrashLibrary.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github 2 | 3 | /** 4 | * Created by idisfkj on 2019-08-13. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | object FakeCrashLibrary { 8 | 9 | fun log(priority: Int, tag: String?, message: String) {} 10 | 11 | fun logWarning(t: Throwable) {} 12 | 13 | fun logError(t: Throwable) {} 14 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/factory/Factory.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.factory 2 | 3 | import com.idisfkj.awesome.componentbridge.BridgeInterface 4 | 5 | /** 6 | * Created by idisfkj on 2019-08-29. 7 | * Email : idisfkj@gmail.com. 8 | */ 9 | interface Factory { 10 | 11 | fun create(bridgeClazz: Class): T 12 | } -------------------------------------------------------------------------------- /common/src/main/res/drawable/corners_2_solid_white_stroke_1_darker_gray_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/user/DefaultUserBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.user 2 | 3 | import androidx.fragment.app.Fragment 4 | 5 | /** 6 | * Created by idisfkj on 2019-11-15. 7 | * Email: idisfkj@gmail.com. 8 | */ 9 | class DefaultUserBridge : UserBridgeInterface{ 10 | 11 | override fun getUserFragment(): Fragment = Fragment() 12 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/home/DefaultHomeBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.home 2 | 3 | import androidx.fragment.app.Fragment 4 | 5 | /** 6 | * Created by idisfkj on 2019-09-02. 7 | * Email : idisfkj@gmail.com. 8 | */ 9 | class DefaultHomeBridge : HomeBridgeInterface { 10 | 11 | override fun getHomeFragment(): Fragment = Fragment() 12 | } -------------------------------------------------------------------------------- /login/src/main/java/com/idisfkj/awesome/login/RequestModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.login 2 | 3 | /** 4 | * Created by idisfkj on 2019-08-30. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | data class IssuesRequestModel(val title: String) 8 | 9 | data class TokenRequestModel( 10 | val client_id: String, 11 | val client_secret: String, 12 | val code: String, 13 | val redirect_uri: String 14 | ) 15 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/search/DefaultSearchBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.search 2 | 3 | import androidx.fragment.app.Fragment 4 | 5 | /** 6 | * Created by idisfkj on 2019-12-01. 7 | * Email: idisfkj@gmail.com. 8 | */ 9 | class DefaultSearchBridge : SearchBridgeInterface { 10 | 11 | override fun getSearchFragment(): Fragment = Fragment() 12 | 13 | } -------------------------------------------------------------------------------- /home/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Home 3 | Home 4 | user avatar 5 | Repos 6 | Gists 7 | Followers 8 | Following 9 | 10 | -------------------------------------------------------------------------------- /login/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Login 3 | Sign in to Github 4 | Username or email address 5 | Password 6 | Sign in 7 | Authorize 8 | 9 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/user/UserBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.user 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-15. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | interface UserBridgeInterface: BridgeInterface { 11 | 12 | fun getUserFragment(): Fragment 13 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/home/HomeBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.home 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-09-02. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | interface HomeBridgeInterface: BridgeInterface { 11 | 12 | fun getHomeFragment(): Fragment 13 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/notification/DefaultNotificationBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.notification 2 | 3 | import androidx.fragment.app.Fragment 4 | 5 | /** 6 | * Created by idisfkj on 2019-11-27. 7 | * Email: idisfkj@gmail.com. 8 | */ 9 | class DefaultNotificationBridge : NotificationBridgeInterface { 10 | 11 | override fun getNotificationFragment(): Fragment = Fragment() 12 | 13 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/search/SearchBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.search 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-12-01. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | interface SearchBridgeInterface : BridgeInterface { 11 | 12 | fun getSearchFragment(): Fragment 13 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/following/FollowingBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.following 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-26. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | interface FollowingBridgeInterface : BridgeInterface { 11 | 12 | fun toFollowingActivity(context: Context) 13 | } -------------------------------------------------------------------------------- /repos/src/test/java/com/example/repos/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.repos 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /home/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /user/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/followers/FollowersBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.followers 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-21. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | interface FollowersBridgeInterface : BridgeInterface { 11 | 12 | fun toFollowersActivity(context: Context) 13 | 14 | } -------------------------------------------------------------------------------- /home/src/test/java/com/idisfkj/awesome/home/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /login/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /repos/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /user/src/test/java/com/idisfkj/awesome/user/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.user 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /login/src/test/java/com/idisfkj/awesome/login/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.login 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /search/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /search/src/test/java/com/idisfkj/awesome/search/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/notification/NotificationBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.notification 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-27. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | interface NotificationBridgeInterface : BridgeInterface { 11 | 12 | fun getNotificationFragment(): Fragment 13 | } -------------------------------------------------------------------------------- /notification/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webview/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webview/src/test/java/com/idisfkj/awesome/webview/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /followers/src/test/java/com/idisfkj/awesome/followers/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /following/src/test/java/com/idisfkj/awesome/following/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/test/java/com/idisfkj/awesome/awesome/github/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.awesome.github 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /followers/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /following/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /notification/src/test/java/com/idisfkj/awesome/notification/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/webview/WebViewBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.webview 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.componentbridge.BridgeInterface 5 | 6 | /** 7 | * Created by idisfkj on 2019-12-03. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | interface WebViewBridgeInterface : BridgeInterface { 11 | 12 | fun toWebViewActivity(context: Context, url: String = "", requestUrl: String = "") 13 | 14 | } -------------------------------------------------------------------------------- /basic/src/test/java/com/idisfkj/awesome/basic/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /user/src/main/java/com/idisfkj/awesome/user/bridge/UserBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.user.bridge 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.user.UserBridgeInterface 5 | import com.idisfkj.awesome.user.fragment.UserFragment 6 | 7 | /** 8 | * Created by idisfkj on 2019-11-15. 9 | * Email: idisfkj@gmail.com. 10 | */ 11 | class UserBridge : UserBridgeInterface { 12 | 13 | override fun getUserFragment(): Fragment = UserFragment.getInstance() 14 | 15 | } -------------------------------------------------------------------------------- /common/src/test/java/com/idisfkj/awesome/common/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/fragment/vm/HomeUserInfoVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home.fragment.vm 2 | 3 | import com.idisfkj.awesome.basic.BaseRecyclerVM 4 | import com.idisfkj.awesome.common.model.UserModel 5 | 6 | /** 7 | * Created by idisfkj on 2019-09-04. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | class HomeUserInfoVM : BaseRecyclerVM() { 11 | var data: UserModel? = null 12 | 13 | override fun onBind(model: UserModel?) { 14 | data = model 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /basic/src/main/java/com/idisfkj/awesome/basic/BaseRecyclerVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic 2 | 3 | import androidx.lifecycle.AndroidViewModel 4 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 5 | import com.idisfkj.awesome.common.utils.CommonUtils 6 | 7 | /** 8 | * Created by idisfkj on 2019-09-04. 9 | * Email : idisfkj@gmail.com. 10 | */ 11 | abstract class BaseRecyclerVM : 12 | AndroidViewModel(CommonUtils.getApp()) { 13 | 14 | abstract fun onBind(model: T?) 15 | } -------------------------------------------------------------------------------- /search/src/main/java/com/idisfkj/awesome/search/bridge/SearchBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search.bridge 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.search.SearchBridgeInterface 5 | import com.idisfkj.awesome.search.fragment.SearchFragment 6 | 7 | /** 8 | * Created by idisfkj on 2019-12-01. 9 | * Email: idisfkj@gmail.com. 10 | */ 11 | class SearchBridge : SearchBridgeInterface { 12 | 13 | override fun getSearchFragment(): Fragment = SearchFragment.getInstance() 14 | 15 | } -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/bridge/HomeBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home.bridge 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.home.HomeBridgeInterface 5 | import com.idisfkj.awesome.home.fragment.HomeFragment 6 | 7 | /** 8 | * Created by idisfkj on 2019-09-02. 9 | * Email : idisfkj@gmail.com. 10 | */ 11 | class HomeBridge : HomeBridgeInterface { 12 | 13 | override fun getHomeFragment(): Fragment { 14 | return HomeFragment.getInstance() 15 | } 16 | } -------------------------------------------------------------------------------- /network/src/test/java/com/idisfkj/awesome/awesome/network/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.awesome.network; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /componentbridge/src/test/java/com/idisfkj/awesome/componentbridge/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/followers/DefaultFollowersBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.followers 2 | 3 | import android.content.Context 4 | import android.widget.Toast 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-21. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | class DefaultFollowersBridge : FollowersBridgeInterface { 11 | 12 | override fun toFollowersActivity(context: Context) { 13 | Toast.makeText(context, "toFollowersActivity", Toast.LENGTH_LONG).show() 14 | } 15 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/following/DefaultFollowingBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.following 2 | 3 | import android.content.Context 4 | import android.widget.Toast 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-26. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | class DefaultFollowingBridge : FollowingBridgeInterface { 11 | 12 | override fun toFollowingActivity(context: Context) { 13 | Toast.makeText(context, "toFollowingActivity", Toast.LENGTH_LONG).show() 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selector_sign_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/navigation/OnNavigationListenerImpl.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.navigation 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | 6 | /** 7 | * Created by idisfkj on 2019-08-29. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | class OnNavigationListenerImpl(private val context: Context) : OnNavigationListener { 11 | 12 | override fun onBackClick() { 13 | (context as? Activity)?.onBackPressed() 14 | } 15 | 16 | override fun onRightIconClick() { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/webview/DefaultWebViewBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.webview 2 | 3 | import android.content.Context 4 | import android.widget.Toast 5 | 6 | /** 7 | * Created by idisfkj on 2019-12-03. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | class DefaultWebViewBridge : WebViewBridgeInterface { 11 | 12 | override fun toWebViewActivity(context: Context, url: String, requestUrl: String) { 13 | Toast.makeText(context, "toWebViewActivity: $url", Toast.LENGTH_LONG).show() 14 | } 15 | } -------------------------------------------------------------------------------- /login/src/main/res/drawable/login_bg_selector_sign_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/repos/ReposBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.repos 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 5 | import com.idisfkj.awesome.componentbridge.BridgeInterface 6 | 7 | /** 8 | * Created by idisfkj on 2019-11-19. 9 | * Email: idisfkj@gmail.com. 10 | */ 11 | interface ReposBridgeInterface: BridgeInterface { 12 | 13 | fun toReposActivity(context: Context) 14 | 15 | fun createReposAdapter(): BaseRecyclerViewAdapter 16 | } -------------------------------------------------------------------------------- /basic/src/main/java/com/idisfkj/awesome/basic/BaseVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic 2 | 3 | import android.os.Bundle 4 | import androidx.lifecycle.AndroidViewModel 5 | import com.idisfkj.awesome.common.live.SingleLiveEvent 6 | import com.idisfkj.awesome.common.utils.CommonUtils 7 | 8 | /** 9 | * Created by idisfkj on 2019-08-30. 10 | * Email : idisfkj@gmail.com. 11 | */ 12 | abstract class BaseVM : AndroidViewModel(CommonUtils.getApp()) { 13 | 14 | val showLoading = SingleLiveEvent() 15 | 16 | abstract fun attach(savedInstanceState: Bundle? = null) 17 | 18 | } 19 | -------------------------------------------------------------------------------- /notification/src/main/java/com/idisfkj/awesome/notification/bridge/NotificationBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification.bridge 2 | 3 | import androidx.fragment.app.Fragment 4 | import com.idisfkj.awesome.componentbridge.notification.NotificationBridgeInterface 5 | import com.idisfkj.awesome.notification.fragment.NotificationFragment 6 | 7 | /** 8 | * Created by idisfkj on 2019-11-27. 9 | * Email: idisfkj@gmail.com. 10 | */ 11 | class NotificationBridge : NotificationBridgeInterface { 12 | 13 | override fun getNotificationFragment(): Fragment = NotificationFragment.getInstance() 14 | } -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/ToPageStatus.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common 2 | 3 | /** 4 | * Created by idisfkj on 2019-08-30. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | sealed class ToPageStatus 8 | 9 | object PageDefault : ToPageStatus() 10 | object WelcomeToMain : ToPageStatus() 11 | object WelcomeToLogin : ToPageStatus() 12 | object LoginToMain : ToPageStatus() 13 | object LoginToAuthorize: ToPageStatus() 14 | object UserToRepos: ToPageStatus() 15 | object UserToFollowers: ToPageStatus() 16 | object UserToFollowing: ToPageStatus() 17 | object ReposToWebView: ToPageStatus() 18 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common 2 | 3 | /** 4 | * Created by idisfkj on 2019-08-30. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | object Constants { 8 | const val AUTHORIZATION_CODE = "code" 9 | const val CLIENT_ID = "a36f72d09eb4c9ee207a" 10 | const val CLIENT_SECRET = "c11cfe68bfc7a8c4753bfdbf036a94ff943b972c" 11 | const val REDIRECT_URI = "github://login" 12 | const val AUTHORIZATION_URL = 13 | "https://github.com/login/oauth/authorize?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=user%20repo%20notifications%20" 14 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /login/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | #1c313a 7 | 8 | #4CAF50 9 | #8BC34A 10 | #4D8BC34A 11 | #03A9F4 12 | #00BCD4 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /common/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /followers/src/main/java/com/idisfkj/awesome/followers/bridge/FollowersBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers.bridge 2 | 3 | import android.content.Context 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.ARouterPaths 6 | import com.idisfkj.awesome.componentbridge.followers.FollowersBridgeInterface 7 | 8 | /** 9 | * Created by idisfkj on 2019-11-21. 10 | * Email : idisfkj@gmail.com. 11 | */ 12 | class FollowersBridge : FollowersBridgeInterface { 13 | 14 | override fun toFollowersActivity(context: Context) { 15 | ARouter.getInstance().build(ARouterPaths.PATH_FOLLOWERS_FOLLOWERS).navigation(context) 16 | } 17 | } -------------------------------------------------------------------------------- /following/src/main/java/com/idisfkj/awesome/following/bridge/FollowingBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following.bridge 2 | 3 | import android.content.Context 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.ARouterPaths 6 | import com.idisfkj.awesome.componentbridge.following.FollowingBridgeInterface 7 | 8 | /** 9 | * Created by idisfkj on 2019-11-26. 10 | * Email: idisfkj@gmail.com. 11 | */ 12 | class FollowingBridge : FollowingBridgeInterface { 13 | 14 | override fun toFollowingActivity(context: Context) { 15 | ARouter.getInstance().build(ARouterPaths.PATH_FOLLOWING_FOLLOWING).navigation(context) 16 | } 17 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/app/AppBridgeInterface.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.app 2 | 3 | import com.idisfkj.awesome.componentbridge.BridgeInterface 4 | 5 | /** 6 | * Created by idisfkj on 2019-08-29. 7 | * Email : idisfkj@gmail.com. 8 | */ 9 | interface AppBridgeInterface: BridgeInterface { 10 | 11 | /** 12 | * 获取用户的Authorization Basic 13 | */ 14 | fun getAuthorizationBasic(): String? 15 | 16 | fun setAuthorizationBasic(authorization: String?) 17 | 18 | /** 19 | * 获取用户的AccessToken 20 | */ 21 | fun getAccessToken(): String? 22 | 23 | fun setAccessToken(accessToken: String?) 24 | } -------------------------------------------------------------------------------- /common/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #263238 4 | #000a12 5 | #cfd8dc 6 | 7 | #0D000000 8 | #cfd8dc 9 | #455a64 10 | #2175F3 11 | #666666 12 | #999999 13 | #eaeaea 14 | #111111 15 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/repos/DefaultReposBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.repos 2 | 3 | import android.content.Context 4 | import android.widget.Toast 5 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 6 | 7 | /** 8 | * Created by idisfkj on 2019-11-19. 9 | * Email: idisfkj@gmail.com. 10 | */ 11 | class DefaultReposBridge : ReposBridgeInterface { 12 | 13 | override fun createReposAdapter(): BaseRecyclerViewAdapter = 14 | object : BaseRecyclerViewAdapter() {} 15 | 16 | override fun toReposActivity(context: Context) { 17 | Toast.makeText(context, "toReposActivity", Toast.LENGTH_LONG).show() 18 | } 19 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/app/DefaultAppBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.app 2 | 3 | import com.idisfkj.awesome.componentbridge.BuildConfig 4 | 5 | /** 6 | * app bridge default implement 7 | * Created by idisfkj on 2019-09-02. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | class DefaultAppBridge : AppBridgeInterface { 11 | 12 | override fun getAuthorizationBasic(): String? = BuildConfig.AUTHORIZATION_BASIC 13 | 14 | override fun setAuthorizationBasic(authorization: String?) { 15 | 16 | } 17 | 18 | override fun getAccessToken(): String? = BuildConfig.ACCESS_TOKEN 19 | 20 | override fun setAccessToken(accessToken: String?) { 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/startup/AwesomeGithubStartupConfig.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.startup 2 | 3 | import com.idisfkj.awesome.github.BuildConfig 4 | import com.rousetime.android_startup.model.LoggerLevel 5 | import com.rousetime.android_startup.model.StartupConfig 6 | import com.rousetime.android_startup.provider.StartupProviderConfig 7 | 8 | /** 9 | * Created by idisfkj on 2020/8/3. 10 | * Email: idisfkj@gmail.com. 11 | */ 12 | class AwesomeGithubStartupConfig : StartupProviderConfig { 13 | 14 | override fun getConfig(): StartupConfig = 15 | StartupConfig.Builder() 16 | .setLoggerLevel(if (BuildConfig.DEBUG) LoggerLevel.DEBUG else LoggerLevel.NONE) 17 | .build() 18 | } -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/store/BridgeStore.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.store 2 | 3 | import com.idisfkj.awesome.componentbridge.BridgeInterface 4 | 5 | /** 6 | * bridge store 7 | * Created by idisfkj on 2019-08-29. 8 | * Email : idisfkj@gmail.com. 9 | */ 10 | class BridgeStore { 11 | 12 | private val mMap = HashMap() 13 | 14 | fun put(key: String, bridge: BridgeInterface) { 15 | mMap.put(key, bridge)?.onClear() 16 | } 17 | 18 | fun get(key: String): BridgeInterface? = mMap[key] 19 | 20 | fun clear() { 21 | for (item in mMap.values) { 22 | item.onClear() 23 | } 24 | mMap.clear() 25 | } 26 | } -------------------------------------------------------------------------------- /common/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 55dp 4 | 15dp 5 | 20dp 6 | 5dp 7 | 10dp 8 | 15dp 9 | 20dp 10 | 25dp 11 | 12 | 12sp 13 | 14sp 14 | 16sp 15 | 18sp 16 | 20sp 17 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AwesomeGithub 3 | welcome image view 4 | Sign in to Github 5 | Username or email address 6 | Password 7 | Sign in 8 | Authorize 9 | Home 10 | Search 11 | Repository 12 | Notification 13 | User 14 | 再按一次退出应用 15 | 16 | -------------------------------------------------------------------------------- /home/src/androidTest/java/com/idisfkj/awesome/home/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home 2 | 3 | import androidx.test.InstrumentationRegistry 4 | import androidx.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.idisfkj.awesome.home", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /login/src/androidTest/java/com/idisfkj/awesome/login/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.login 2 | 3 | import androidx.test.InstrumentationRegistry 4 | import androidx.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.idisfkj.awesome.login", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /webview/src/main/java/com/idisfkj/awesome/webview/bridge/WebViewBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview.bridge 2 | 3 | import android.content.Context 4 | import androidx.core.os.bundleOf 5 | import com.alibaba.android.arouter.launcher.ARouter 6 | import com.idisfkj.awesome.common.ARouterPaths 7 | import com.idisfkj.awesome.componentbridge.webview.WebViewBridgeInterface 8 | 9 | /** 10 | * Created by idisfkj on 2019-12-03. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | class WebViewBridge : WebViewBridgeInterface { 14 | 15 | override fun toWebViewActivity(context: Context, url: String, requestUrl: String) { 16 | ARouter.getInstance().build(ARouterPaths.PATH_WEBVIEW_WEBVIEW).with( 17 | bundleOf("url" to url, "requestUrl" to requestUrl) 18 | ).navigation(context) 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/idisfkj/awesome/awesome/github/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.awesome.github 2 | 3 | import androidx.test.InstrumentationRegistry 4 | import androidx.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.idisfkj.awesome.awesome.github", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /login/src/main/java/com/idisfkj/awesome/login/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.login 2 | 3 | import android.os.Bundle 4 | import android.widget.TextView 5 | import androidx.appcompat.app.AppCompatActivity 6 | import com.alibaba.android.arouter.facade.annotation.Route 7 | import com.alibaba.android.arouter.launcher.ARouter 8 | import com.idisfkj.awesome.common.ARouterPaths 9 | 10 | @Route(path = ARouterPaths.PATH_LOGIN_MAIN) 11 | class MainActivity : AppCompatActivity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.login_activity_main) 16 | findViewById(R.id.login).setOnClickListener { 17 | ARouter.getInstance().build(ARouterPaths.PATH_LOGIN_LOGIN).navigation() 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /repos/src/androidTest/java/com/example/repos/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.repos 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.example.repository.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /user/src/main/java/com/idisfkj/awesome/user/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.user.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.UserModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import kotlinx.coroutines.CoroutineScope 9 | 10 | /** 11 | * Created by idisfkj on 2019-11-15. 12 | * Email: idisfkj@gmail.com. 13 | */ 14 | class UserRepository( 15 | private val service: GithubService, 16 | scope: CoroutineScope 17 | ) : BaseRepository(scope) { 18 | 19 | fun getUser(callback: RequestCallback) { 20 | request(scope, callback) { 21 | service.getUser() 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /basic/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /common/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /home/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /login/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /network/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /repos/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /search/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /user/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /user/src/androidTest/java/com/idisfkj/awesome/user/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.user 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.idisfkj.awesome.user.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /webview/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /followers/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /following/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /notification/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /repos/src/main/java/com/idisfkj/awesome/repos/bridge/ReposBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.repos.bridge 2 | 3 | import android.content.Context 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 6 | import com.idisfkj.awesome.common.ARouterPaths 7 | import com.idisfkj.awesome.componentbridge.repos.ReposBridgeInterface 8 | import com.idisfkj.awesome.repos.adapter.ReposAdapter 9 | 10 | /** 11 | * Created by idisfkj on 2019-11-19. 12 | * Email: idisfkj@gmail.com. 13 | */ 14 | class ReposBridge : ReposBridgeInterface { 15 | 16 | override fun createReposAdapter(): BaseRecyclerViewAdapter = ReposAdapter() 17 | 18 | override fun toReposActivity(context: Context) { 19 | ARouter.getInstance().build(ARouterPaths.PATH_REPOS_REPOS).navigation(context) 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /search/src/androidTest/java/com/idisfkj/awesome/search/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.idisfkj.awesome.search.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/startup/UtilsStartup.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.startup 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import com.idisfkj.awesome.common.utils.CommonUtils 6 | import com.idisfkj.awesome.common.utils.SPUtils 7 | import com.rousetime.android_startup.AndroidStartup 8 | 9 | /** 10 | * Created by idisfkj on 2020/8/3. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | class UtilsStartup : AndroidStartup() { 14 | 15 | override fun callCreateOnMainThread(): Boolean = true 16 | 17 | override fun waitOnMainThread(): Boolean = true 18 | 19 | override fun create(context: Context): Void? { 20 | (context as? Application)?.let { 21 | SPUtils.init(it) 22 | CommonUtils.initApp(it) 23 | } 24 | 25 | return null 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /componentbridge/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /webview/src/androidTest/java/com/idisfkj/awesome/webview/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.idisfkj.awesome.webview.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/bridge/AppBridge.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.bridge 2 | 3 | import com.idisfkj.awesome.componentbridge.app.AppBridgeInterface 4 | import com.idisfkj.awesome.github.startup.SyncBridgeStartup 5 | 6 | /** 7 | * App Bridge 8 | * Created by idisfkj on 2019-08-29. 9 | * Email : idisfkj@gmail.com. 10 | */ 11 | class AppBridge : AppBridgeInterface { 12 | 13 | override fun getAuthorizationBasic(): String? = SyncBridgeStartup.AUTHORIZATION_BASIC 14 | 15 | override fun setAuthorizationBasic(authorization: String?) { 16 | SyncBridgeStartup.AUTHORIZATION_BASIC = authorization 17 | } 18 | 19 | override fun getAccessToken(): String? = SyncBridgeStartup.ACCESS_TOKEN 20 | 21 | override fun setAccessToken(accessToken: String?) { 22 | SyncBridgeStartup.ACCESS_TOKEN = accessToken 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/factory/NewInstanceFactory.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.factory 2 | 3 | import com.idisfkj.awesome.componentbridge.BridgeInterface 4 | 5 | /** 6 | * Created by idisfkj on 2019-08-29. 7 | * Email : idisfkj@gmail.com. 8 | */ 9 | class NewInstanceFactory : Factory { 10 | 11 | companion object { 12 | val instance: NewInstanceFactory by lazy { NewInstanceFactory() } 13 | } 14 | 15 | override fun create(bridgeClazz: Class): T = try { 16 | bridgeClazz.newInstance() 17 | } catch (e: InstantiationException) { 18 | throw RuntimeException("Cannot create an instance of $bridgeClazz", e) 19 | } catch (e: IllegalAccessException) { 20 | throw RuntimeException("Cannot create an instance of $bridgeClazz", e) 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /followers/src/androidTest/java/com/idisfkj/awesome/followers/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.idisfkj.awesome.followers.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /following/src/androidTest/java/com/idisfkj/awesome/following/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.idisfkj.awesome.following.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/fragment/repository/HomeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home.fragment.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.UserModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import kotlinx.coroutines.CoroutineScope 9 | 10 | /** 11 | * Created by idisfkj on 2019-09-02. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class HomeRepository( 15 | private val service: GithubService, 16 | scope: CoroutineScope 17 | ) : BaseRepository(scope) { 18 | 19 | fun getUser(callback: RequestCallback) { 20 | request(scope, callback) { 21 | service.getUser() 22 | } 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/ARouterPaths.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common 2 | 3 | /** 4 | * Created by idisfkj on 2019-09-02. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | object ARouterPaths { 8 | const val PATH_LOGIN_LOGIN = "/login/login" 9 | const val PATH_LOGIN_MAIN = "/login/main" 10 | 11 | const val PATH_APP_MAIN = "/app/main" 12 | 13 | const val PATH_HOME_MAIN = "home/main" 14 | 15 | const val PATH_USER_MAIN = "/user/main" 16 | 17 | const val PATH_REPOS_REPOS = "/repos/repos" 18 | 19 | const val PATH_FOLLOWERS_FOLLOWERS = "/followers/followers" 20 | 21 | const val PATH_FOLLOWING_FOLLOWING = "/following/following" 22 | 23 | const val PATH_NOTIFICATION_MAIN = "/notification/main" 24 | 25 | const val PATH_SEARCH_MAIN = "/search/main" 26 | 27 | const val PATH_WEBVIEW_WEBVIEW = "/webview/webview" 28 | } -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/NotificationModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-11-27. 5 | * Email: idisfkj@gmail.com. 6 | */ 7 | 8 | data class NotificationModel( 9 | val id: String, 10 | val repository: ReposModel, 11 | val subject: SubjectModel, 12 | val reason: String, 13 | var unread: Boolean, 14 | val updated_at: String, 15 | val last_read_at: String, 16 | val url: String 17 | ) : BaseRecyclerViewModel() 18 | 19 | data class SubjectModel( 20 | val title: String, 21 | val url: String, 22 | val latest_comment_url: String, 23 | val type: String 24 | ) 25 | 26 | data class NotificationRequestUrlModel( 27 | val url: String, 28 | val id: Long, 29 | val html_url: String, 30 | val userModel: UserModel, 31 | val body: String 32 | ) 33 | -------------------------------------------------------------------------------- /login/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /notification/src/androidTest/java/com/idisfkj/awesome/notification/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.idisfkj.awesome.notification.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /followers/src/main/java/com/idisfkj/awesome/followers/repository/FollowersRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.FollowersModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import kotlinx.coroutines.CoroutineScope 9 | 10 | /** 11 | * Created by idisfkj on 2019-11-22. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class FollowersRepository( 15 | private val service: GithubService, 16 | scope: CoroutineScope 17 | ) : BaseRepository(scope) { 18 | 19 | fun getFollowers(callback: RequestCallback>) { 20 | request(scope = scope, callback = callback) { service.getFollowers() } 21 | } 22 | } -------------------------------------------------------------------------------- /basic/src/androidTest/java/com/idisfkj/awesome/basic/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.idisfkj.awesome.basic.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/androidTest/java/com/idisfkj/awesome/common/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.idisfkj.awesome.common.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /repos/src/main/java/com/idisfkj/awesome/repos/repository/ReposRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.repos.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.ReposModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import kotlinx.coroutines.CoroutineScope 9 | 10 | /** 11 | * Created by idisfkj on 2019-11-20. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class ReposRepository( 15 | private val service: GithubService, 16 | scope: CoroutineScope 17 | ) : BaseRepository(scope) { 18 | 19 | fun getRepos(callback: RequestCallback>) { 20 | request(scope, callback) { 21 | service.getPros(mapOf("visibility" to "all", "sort" to "pushed")) 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /following/src/main/java/com/idisfkj/awesome/following/repository/FollowingRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.FollowersModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import kotlinx.coroutines.CoroutineScope 9 | 10 | /** 11 | * Created by idisfkj on 2019-11-26. 12 | * Email: idisfkj@gmail.com. 13 | */ 14 | class FollowingRepository( 15 | private val service: GithubService, 16 | scope: CoroutineScope 17 | ) : BaseRepository(scope) { 18 | 19 | fun getFollowing(callback: RequestCallback>) { 20 | request(scope = scope, callback = callback) { 21 | service.getFollowing() 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/widget/NonScrollViewPager.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.widget 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.MotionEvent 6 | import androidx.viewpager.widget.ViewPager 7 | 8 | /** 9 | * Created by idisfkj on 2019-08-16. 10 | * Email : idisfkj@gmail.com. 11 | */ 12 | class NonScrollViewPager(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) { 13 | 14 | override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { 15 | return false 16 | } 17 | 18 | override fun onTouchEvent(ev: MotionEvent?): Boolean { 19 | if (ev?.action == MotionEvent.ACTION_UP) { 20 | performClick() 21 | } 22 | return true 23 | } 24 | 25 | override fun performClick(): Boolean { 26 | super.performClick() 27 | return true 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /home/src/main/res/layout/home_activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | # Built application files 3 | *.apk 4 | *.ap_ 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Log Files 28 | *.log 29 | 30 | # Android Studio Navigation editor temp files 31 | .navigation/ 32 | 33 | # Android Studio captures folder 34 | captures/ 35 | 36 | # IntelliJ 37 | *.iml 38 | .idea 39 | 40 | # Keystore files 41 | # Uncomment the following line if you do not want to check your keystore files in. 42 | #*.jks 43 | 44 | # External native build folder generated in Android Studio 2.2 and later 45 | .externalNativeBuild 46 | 47 | # Google Services (e.g. APIs or Firebase) 48 | google-services.json 49 | -------------------------------------------------------------------------------- /repos/src/main/java/com/idisfkj/awesome/repos/ReposActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.repos 2 | 3 | import com.alibaba.android.arouter.facade.annotation.Route 4 | import com.idisfkj.awesome.basic.activity.BaseActivity 5 | import com.idisfkj.awesome.common.ARouterPaths 6 | import com.idisfkj.awesome.repos.databinding.ReposActivityMainLayoutBinding 7 | import com.idisfkj.awesome.repos.vm.ReposVM 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-19. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | @Route(path = ARouterPaths.PATH_REPOS_REPOS) 14 | class ReposActivity : BaseActivity() { 15 | 16 | override fun getVariableId(): Int = BR.vm 17 | 18 | override fun getLayoutId(): Int = R.layout.repos_activity_main_layout 19 | 20 | override fun getViewModelInstance(): ReposVM = ReposVM() 21 | 22 | override fun getViewModelClass(): Class = ReposVM::class.java 23 | 24 | } -------------------------------------------------------------------------------- /user/src/main/res/layout/user_activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /following/src/main/java/com/idisfkj/awesome/following/vm/FollowingVHVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following.vm 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.basic.BaseRecyclerVM 5 | import com.idisfkj.awesome.common.model.FollowersModel 6 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 7 | import com.idisfkj.awesome.componentbridge.webview.WebViewBridgeInterface 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-26. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | class FollowingVHVM(private val context: Context) : BaseRecyclerVM() { 14 | 15 | var data: FollowersModel? = null 16 | 17 | override fun onBind(model: FollowersModel?) { 18 | data = model 19 | } 20 | 21 | fun contentClick() { 22 | BridgeProviders.instance.getBridge(WebViewBridgeInterface::class.java) 23 | .toWebViewActivity(context, data?.html_url ?: "", "") 24 | } 25 | } -------------------------------------------------------------------------------- /webview/src/main/res/layout/webview_activity_webview_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 16 | 17 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /followers/src/main/java/com/idisfkj/awesome/followers/vm/FollowersVHVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers.vm 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.basic.BaseRecyclerVM 5 | import com.idisfkj.awesome.common.model.FollowersModel 6 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 7 | import com.idisfkj.awesome.componentbridge.webview.WebViewBridgeInterface 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-22. 11 | * Email : idisfkj@gmail.com. 12 | */ 13 | class FollowersVHVM(private val context: Context) : BaseRecyclerVM() { 14 | 15 | var data: FollowersModel? = null 16 | 17 | override fun onBind(model: FollowersModel?) { 18 | data = model 19 | } 20 | 21 | fun contentClick() { 22 | BridgeProviders.instance.getBridge(WebViewBridgeInterface::class.java) 23 | .toWebViewActivity(context, data?.html_url ?: "", "") 24 | } 25 | } -------------------------------------------------------------------------------- /network/src/androidTest/java/com/idisfkj/awesome/awesome/network/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.awesome.network; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.idisfkj.awesome.awesome.network.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /search/src/main/res/layout/search_activity_main_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /componentbridge/src/androidTest/java/com/idisfkj/awesome/componentbridge/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.idisfkj.awesome.componentbridage.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /notification/src/main/res/layout/notify_activity_main_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /search/src/main/java/com/idisfkj/awesome/search/repository/SearchRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.SearchModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import kotlinx.coroutines.CoroutineScope 9 | 10 | /** 11 | * Created by idisfkj on 2019-12-02. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class SearchRepository( 15 | private val service: GithubService, 16 | scope: CoroutineScope 17 | ) : BaseRepository(scope) { 18 | 19 | fun searchRepository(query: String, callback: RequestCallback) { 20 | request( 21 | scope = scope, 22 | callback = callback 23 | ) { service.searchRepository(hashMapOf("q" to query)) } 24 | } 25 | } -------------------------------------------------------------------------------- /user/src/main/java/com/idisfkj/awesome/user/UserMainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.user 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.alibaba.android.arouter.facade.annotation.Route 6 | import com.idisfkj.awesome.common.ARouterPaths 7 | import com.idisfkj.awesome.user.fragment.UserFragment 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-15. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | @Route(path = ARouterPaths.PATH_USER_MAIN) 14 | class UserMainActivity : AppCompatActivity() { 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | setContentView(R.layout.user_activity_main) 18 | addFragment() 19 | } 20 | 21 | private fun addFragment() { 22 | supportFragmentManager.beginTransaction() 23 | .replace(R.id.fragment_layout, UserFragment.getInstance()) 24 | .commit() 25 | } 26 | } -------------------------------------------------------------------------------- /login/src/main/res/layout/login_activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/ResponseModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-09-04. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | 8 | const val TYPE_INFO = 1 9 | 10 | data class UserModel( 11 | val id: String, 12 | val login: String, 13 | val avatar_url: String, 14 | val name: String, 15 | val public_repos: Int, 16 | val public_gists: Int, 17 | val followers: Int, 18 | val following: Int, 19 | val email: String, 20 | val blog: String, 21 | val company: String?, 22 | val location: String, 23 | val url: String, 24 | val bio: String, 25 | val node_id: String, 26 | val total_private_repos: Int 27 | ) : BaseRecyclerViewModel(itemType = TYPE_INFO) 28 | 29 | data class IssuesModel( 30 | val id: Int, 31 | val node_id: String, 32 | val url: String, 33 | val state: String, 34 | val title: String, 35 | val body: String 36 | ) 37 | 38 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/utils/LoadingUtils.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.utils 2 | 3 | import android.view.ViewGroup 4 | import com.idisfkj.awesome.common.custom.LoadingView 5 | 6 | /** 7 | * Created by idisfkj on 2019-11-13. 8 | * Email: idisfkj@gmail.com. 9 | */ 10 | object LoadingUtils { 11 | 12 | fun loading(show: Boolean, target: ViewGroup?) { 13 | if (show) showLoading(target) else dismissLoading(target) 14 | } 15 | 16 | private fun showLoading(target: ViewGroup?) { 17 | target?.run { 18 | if (childCount <= 0 || getChildAt(childCount - 1) !is LoadingView) { 19 | addView(LoadingView(context)) 20 | } 21 | } 22 | } 23 | 24 | private fun dismissLoading(target: ViewGroup?) { 25 | target?.run { 26 | if (childCount > 0 && getChildAt(childCount - 1) is LoadingView) { 27 | removeViewAt(childCount - 1) 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /followers/src/main/java/com/idisfkj/awesome/followers/FollowersActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers 2 | 3 | import com.alibaba.android.arouter.facade.annotation.Route 4 | import com.idisfkj.awesome.basic.activity.BaseActivity 5 | import com.idisfkj.awesome.common.ARouterPaths 6 | import com.idisfkj.awesome.followers.databinding.FollowersActivityFollowersLayoutBinding 7 | import com.idisfkj.awesome.followers.vm.FollowersVM 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-21. 11 | * Email : idisfkj@gmail.com. 12 | */ 13 | @Route(path = ARouterPaths.PATH_FOLLOWERS_FOLLOWERS) 14 | class FollowersActivity : BaseActivity() { 15 | 16 | override fun getVariableId(): Int = BR.vm 17 | 18 | override fun getLayoutId(): Int = R.layout.followers_activity_followers_layout 19 | 20 | override fun getViewModelInstance(): FollowersVM = FollowersVM() 21 | 22 | override fun getViewModelClass(): Class = FollowersVM::class.java 23 | } -------------------------------------------------------------------------------- /following/src/main/java/com/idisfkj/awesome/following/FollowingActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following 2 | 3 | import com.alibaba.android.arouter.facade.annotation.Route 4 | import com.idisfkj.awesome.basic.activity.BaseActivity 5 | import com.idisfkj.awesome.common.ARouterPaths 6 | import com.idisfkj.awesome.following.databinding.FollowingActivityFollowingLayoutBinding 7 | import com.idisfkj.awesome.following.vm.FollowingVM 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-26. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | @Route(path = ARouterPaths.PATH_FOLLOWING_FOLLOWING) 14 | class FollowingActivity : BaseActivity() { 15 | 16 | override fun getVariableId(): Int = BR.vm 17 | 18 | override fun getLayoutId(): Int = R.layout.following_activity_following_layout 19 | 20 | override fun getViewModelInstance(): FollowingVM = FollowingVM() 21 | 22 | override fun getViewModelClass(): Class = FollowingVM::class.java 23 | } -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.alibaba.android.arouter.facade.annotation.Route 6 | import com.idisfkj.awesome.common.ARouterPaths 7 | import com.idisfkj.awesome.home.fragment.HomeFragment 8 | import timber.log.Timber 9 | 10 | @Route(path = ARouterPaths.PATH_HOME_MAIN) 11 | class MainActivity : AppCompatActivity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | Timber.d("========== onCreate ===========") 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.home_activity_main) 17 | addFragment() 18 | } 19 | 20 | private fun addFragment() { 21 | Timber.d("========== addFragment ===========") 22 | supportFragmentManager.beginTransaction() 23 | .replace(R.id.fragment_layout, HomeFragment.getInstance()) 24 | .commit() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/model/ReposModel.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.model 2 | 3 | /** 4 | * Created by idisfkj on 2019-11-19. 5 | * Email : idisfkj@gmail.com. 6 | */ 7 | 8 | data class ReposModel( 9 | val id: Int, 10 | val name: String, 11 | val full_name: String, 12 | val private: Boolean, 13 | val owner: OwnerModel, 14 | val description: String, 15 | val fork: Boolean, 16 | val url: String, 17 | val html_url: String, 18 | val created_at: String, 19 | val updated_at: String, 20 | val pushed_at: String, 21 | val stargazers_count: Int, 22 | val watchers_count: Int, 23 | val homePage: String, 24 | val language: String, 25 | val forks_count: Int, 26 | val open_issues_count: Int, 27 | val license: License? 28 | ): BaseRecyclerViewModel() 29 | 30 | data class OwnerModel( 31 | val login: String, 32 | val id: Int, 33 | val avatar_url: String 34 | ) 35 | 36 | data class License(val name: String) 37 | -------------------------------------------------------------------------------- /search/src/main/java/com/idisfkj/awesome/search/fragment/SearchFragment.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search.fragment 2 | 3 | import com.idisfkj.awesome.basic.fragment.BaseFragment 4 | import com.idisfkj.awesome.search.BR 5 | import com.idisfkj.awesome.search.R 6 | import com.idisfkj.awesome.search.databinding.SearchFragmentSearchLayoutBinding 7 | import com.idisfkj.awesome.search.vm.SearchVM 8 | 9 | /** 10 | * Created by idisfkj on 2019-12-01. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | class SearchFragment : BaseFragment() { 14 | 15 | override fun getVariableId(): Int = BR.vm 16 | 17 | override fun getLayoutId(): Int = R.layout.search_fragment_search_layout 18 | 19 | override fun getViewModelInstance(): SearchVM = SearchVM() 20 | 21 | override fun getViewModelClass(): Class = SearchVM::class.java 22 | 23 | companion object { 24 | fun getInstance(): SearchFragment { 25 | return SearchFragment() 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /notification/src/main/java/com/idisfkj/awesome/notification/NotificationMainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.alibaba.android.arouter.facade.annotation.Route 6 | import com.idisfkj.awesome.common.ARouterPaths 7 | import com.idisfkj.awesome.notification.fragment.NotificationFragment 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-27. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | @Route(path = ARouterPaths.PATH_NOTIFICATION_MAIN) 14 | class NotificationMainActivity : AppCompatActivity() { 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setContentView(R.layout.notify_activity_main_layout) 19 | addFragment() 20 | } 21 | 22 | private fun addFragment() { 23 | supportFragmentManager.beginTransaction() 24 | .replace(R.id.fragment_layout, NotificationFragment.getInstance()) 25 | .commit() 26 | } 27 | } -------------------------------------------------------------------------------- /login/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /repos/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /home/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /user/src/main/java/com/idisfkj/awesome/user/vm/UserInfoVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.user.vm 2 | 3 | import com.idisfkj.awesome.basic.BaseRecyclerVM 4 | import com.idisfkj.awesome.common.ToPageStatus 5 | import com.idisfkj.awesome.common.UserToFollowers 6 | import com.idisfkj.awesome.common.UserToFollowing 7 | import com.idisfkj.awesome.common.UserToRepos 8 | import com.idisfkj.awesome.common.live.SingleLiveEvent 9 | import com.idisfkj.awesome.common.model.UserModel 10 | 11 | /** 12 | * Created by idisfkj on 2019-11-15. 13 | * Email: idisfkj@gmail.com. 14 | */ 15 | class UserInfoVM : BaseRecyclerVM() { 16 | 17 | var data: UserModel? = null 18 | var navigate: SingleLiveEvent = SingleLiveEvent() 19 | 20 | override fun onBind(model: UserModel?) { 21 | data = model 22 | } 23 | 24 | fun reposClick() { 25 | navigate.value = UserToRepos 26 | } 27 | 28 | fun followersClick() { 29 | navigate.value = UserToFollowers 30 | } 31 | 32 | fun followingClick() { 33 | navigate.value = UserToFollowing 34 | } 35 | } -------------------------------------------------------------------------------- /user/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | # ARouter start 24 | -keep public class com.alibaba.android.arouter.routes.**{*;} 25 | -keep public class com.alibaba.android.arouter.facade.**{*;} 26 | -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} 27 | # ARouter end 28 | -------------------------------------------------------------------------------- /followers/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /following/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /search/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /search/src/main/java/com/idisfkj/awesome/search/SearchMainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.alibaba.android.arouter.facade.annotation.Route 6 | import com.idisfkj.awesome.common.ARouterPaths 7 | import com.idisfkj.awesome.search.fragment.SearchFragment 8 | import timber.log.Timber 9 | 10 | /** 11 | * Created by idisfkj on 2019-12-01. 12 | * Email: idisfkj@gmail.com. 13 | */ 14 | @Route(path = ARouterPaths.PATH_SEARCH_MAIN) 15 | class SearchMainActivity : AppCompatActivity() { 16 | 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | Timber.d("========== onCreate ===========") 19 | super.onCreate(savedInstanceState) 20 | setContentView(R.layout.search_activity_main_layout) 21 | addFragment() 22 | } 23 | 24 | private fun addFragment() { 25 | Timber.d("========== addFragment ===========") 26 | supportFragmentManager.beginTransaction() 27 | .replace(R.id.fragment_layout, SearchFragment.getInstance()) 28 | .commit() 29 | } 30 | } -------------------------------------------------------------------------------- /notification/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/HomeApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import timber.log.Timber 9 | 10 | /** 11 | * Created by idisfkj on 2019-09-03. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class HomeApp : Application() { 15 | 16 | override fun onCreate() { 17 | super.onCreate() 18 | SPUtils.init(this) 19 | initTimber() 20 | initRouter() 21 | // register bridges 22 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 23 | } 24 | 25 | private fun initTimber() { 26 | if (BuildConfig.DEBUG) { 27 | Timber.plant(Timber.DebugTree()) 28 | } 29 | } 30 | 31 | private fun initRouter() { 32 | if (BuildConfig.DEBUG) { 33 | ARouter.openLog() 34 | ARouter.openDebug() 35 | } 36 | ARouter.init(this) 37 | } 38 | } -------------------------------------------------------------------------------- /notification/src/main/java/com/idisfkj/awesome/notification/fragment/NotificationFragment.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification.fragment 2 | 3 | import com.idisfkj.awesome.basic.fragment.BaseFragment 4 | import com.idisfkj.awesome.notification.BR 5 | import com.idisfkj.awesome.notification.R 6 | import com.idisfkj.awesome.notification.databinding.NotifyFragmentNotificationLayoutBinding 7 | import com.idisfkj.awesome.notification.vm.NotificationVM 8 | 9 | /** 10 | * Created by idisfkj on 2019-11-27. 11 | * Email: idisfkj@gmail.com. 12 | */ 13 | class NotificationFragment : 14 | BaseFragment() { 15 | 16 | override fun getVariableId(): Int = BR.vm 17 | 18 | override fun getLayoutId(): Int = R.layout.notify_fragment_notification_layout 19 | 20 | override fun getViewModelInstance(): NotificationVM = NotificationVM(lifecycle) 21 | 22 | override fun getViewModelClass(): Class = NotificationVM::class.java 23 | 24 | companion object { 25 | fun getInstance(): NotificationFragment { 26 | return NotificationFragment() 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /login/src/main/java/com/idisfkj/awesome/login/LoginApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.login 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import timber.log.Timber 9 | 10 | /** 11 | * Created by idisfkj on 2019-09-02. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class LoginApp : Application() { 15 | 16 | override fun onCreate() { 17 | super.onCreate() 18 | SPUtils.init(this) 19 | initTimber() 20 | initRouter() 21 | // register bridges 22 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 23 | } 24 | 25 | private fun initTimber() { 26 | if (BuildConfig.DEBUG) { 27 | Timber.plant(Timber.DebugTree()) 28 | } 29 | } 30 | 31 | private fun initRouter() { 32 | if (BuildConfig.DEBUG) { 33 | ARouter.openLog() 34 | ARouter.openDebug() 35 | } 36 | ARouter.init(this) 37 | } 38 | } -------------------------------------------------------------------------------- /followers/src/main/java/com/idisfkj/awesome/followers/adapter/FollowersAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers.adapter 2 | 3 | import android.view.ViewGroup 4 | import androidx.databinding.ViewDataBinding 5 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 6 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewVH 7 | import com.idisfkj.awesome.basic.recyclerview.CommonRecyclerViewVH 8 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 9 | import com.idisfkj.awesome.followers.BR 10 | import com.idisfkj.awesome.followers.R 11 | import com.idisfkj.awesome.followers.vm.FollowersVHVM 12 | 13 | /** 14 | * Created by idisfkj on 2019-11-22. 15 | * Email : idisfkj@gmail.com. 16 | */ 17 | class FollowersAdapter : BaseRecyclerViewAdapter() { 18 | 19 | override fun onCreateViewHolder( 20 | parent: ViewGroup, 21 | viewType: Int 22 | ): BaseRecyclerViewVH { 23 | return CommonRecyclerViewVH( 24 | parent, 25 | R.layout.followers_item_followers_layout, 26 | FollowersVHVM(parent.context), 27 | BR.vm 28 | ) 29 | } 30 | } -------------------------------------------------------------------------------- /following/src/main/java/com/idisfkj/awesome/following/adapter/FollowingAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following.adapter 2 | 3 | import android.view.ViewGroup 4 | import androidx.databinding.ViewDataBinding 5 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 6 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewVH 7 | import com.idisfkj.awesome.basic.recyclerview.CommonRecyclerViewVH 8 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 9 | import com.idisfkj.awesome.following.BR 10 | import com.idisfkj.awesome.following.R 11 | import com.idisfkj.awesome.following.vm.FollowingVHVM 12 | 13 | /** 14 | * Created by idisfkj on 2019-11-26. 15 | * Email: idisfkj@gmail.com. 16 | */ 17 | class FollowingAdapter : BaseRecyclerViewAdapter() { 18 | 19 | override fun onCreateViewHolder( 20 | parent: ViewGroup, 21 | viewType: Int 22 | ): BaseRecyclerViewVH { 23 | return CommonRecyclerViewVH( 24 | parent, 25 | R.layout.following_item_following_layout, 26 | FollowingVHVM(parent.context), 27 | BR.vm 28 | ) 29 | } 30 | } -------------------------------------------------------------------------------- /network/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | apply plugin: 'kotlin-android' 6 | 7 | apply plugin: 'kotlin-kapt' 8 | 9 | android { 10 | compileSdkVersion Versions.target_sdk 11 | buildToolsVersion Versions.build_tools 12 | 13 | 14 | defaultConfig { 15 | minSdkVersion Versions.min_sdk 16 | targetSdkVersion Versions.target_sdk 17 | versionCode Versions.version_code 18 | versionName Versions.version_name 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | 31 | } 32 | 33 | dependencies { 34 | implementation project(':componentbridge') 35 | implementation project(':common') 36 | 37 | // retrofit 38 | api Deps.retrofit_runtime 39 | api Deps.retrofit_gson 40 | api Deps.okhttp_logging_interceptor 41 | api Deps.retrofit_adapter_rxjava2 42 | } 43 | 44 | repositories { 45 | mavenCentral() 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/startup/AsyncBridgeStartup.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.startup 2 | 3 | import android.content.Context 4 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 5 | import com.idisfkj.awesome.followers.bridge.FollowersBridge 6 | import com.idisfkj.awesome.following.bridge.FollowingBridge 7 | import com.idisfkj.awesome.webview.bridge.WebViewBridge 8 | import com.rousetime.android_startup.AndroidStartup 9 | 10 | /** 11 | * non first-level page bridge initialize, so can executor on other thread. 12 | * Created by idisfkj on 2020/8/3. 13 | * Email: idisfkj@gmail.com. 14 | */ 15 | class AsyncBridgeStartup : AndroidStartup() { 16 | 17 | override fun callCreateOnMainThread(): Boolean = false 18 | 19 | override fun waitOnMainThread(): Boolean = false 20 | 21 | override fun create(context: Context): Void? { 22 | registerBridge() 23 | return null 24 | } 25 | 26 | private fun registerBridge() { 27 | BridgeProviders.instance 28 | .register(FollowersBridge::class.java) 29 | .register(FollowingBridge::class.java) 30 | .register(WebViewBridge::class.java) 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /webview/src/main/manifest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/fragment/HomeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home.fragment 2 | 3 | import androidx.lifecycle.Observer 4 | import com.idisfkj.awesome.basic.fragment.BaseFragment 5 | import com.idisfkj.awesome.home.BR 6 | import com.idisfkj.awesome.home.R 7 | import com.idisfkj.awesome.home.databinding.HomeFragmentHomeBinding 8 | import com.idisfkj.awesome.home.fragment.vm.HomeVM 9 | import timber.log.Timber 10 | 11 | /** 12 | * Created by idisfkj on 2019-09-02. 13 | * Email : idisfkj@gmail.com. 14 | */ 15 | class HomeFragment : BaseFragment() { 16 | 17 | override fun getVariableId(): Int = BR.vm 18 | 19 | override fun getLayoutId(): Int = R.layout.home_fragment_home 20 | 21 | override fun getViewModelInstance(): HomeVM = HomeVM() 22 | 23 | override fun getViewModelClass(): Class = HomeVM::class.java 24 | 25 | companion object { 26 | fun getInstance(): HomeFragment { 27 | return HomeFragment() 28 | } 29 | } 30 | 31 | override fun addObserver() { 32 | super.addObserver() 33 | viewModel.userData.observe(this, Observer { 34 | Timber.d("addObserver %s", it.followers) 35 | }) 36 | } 37 | } -------------------------------------------------------------------------------- /webview/src/main/java/com/idisfkj/awesome/webview/repository/WebViewRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview.repository 2 | 3 | import com.idisfkj.awesome.basic.repository.BaseRepository 4 | import com.idisfkj.awesome.common.extensions.RequestCallback 5 | import com.idisfkj.awesome.common.extensions.request 6 | import com.idisfkj.awesome.common.model.NotificationRequestUrlModel 7 | import com.idisfkj.awesome.network.GithubService 8 | import com.idisfkj.awesome.network.HttpClient 9 | import kotlinx.coroutines.CoroutineScope 10 | 11 | /** 12 | * Created by idisfkj on 2019-12-03. 13 | * Email : idisfkj@gmail.com. 14 | */ 15 | class WebViewRepository( 16 | private val service: GithubService, 17 | scope: CoroutineScope 18 | ) : BaseRepository(scope) { 19 | 20 | fun getNotificationRequestUrl( 21 | path: String, 22 | callback: RequestCallback 23 | ) { 24 | val finalPath = if (path.startsWith(HttpClient.API_GITHUB_BASE_URL)) { 25 | path.substring(HttpClient.API_GITHUB_BASE_URL.length + 1) 26 | } else { 27 | path 28 | } 29 | request(scope, callback) { 30 | service.getNotificationRequestUrl(finalPath) 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/extensions/CommonExtensions.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.extensions 2 | 3 | import android.text.Editable 4 | import android.text.TextWatcher 5 | import android.view.View 6 | 7 | /** 8 | * Created by idisfkj on 2019-08-30. 9 | * Email : idisfkj@gmail.com. 10 | */ 11 | inline fun createTextWatcher( 12 | crossinline afterTextChanged: (s: Editable?) -> Unit = {}, 13 | crossinline beforeTextChanged: (s: CharSequence?, start: Int, count: Int, after: Int) -> Unit = { _, _, _, _ -> }, 14 | crossinline onTextChanged: (s: CharSequence?, start: Int, before: Int, count: Int) -> Unit = { _, _, _, _ -> } 15 | ) = object : TextWatcher { 16 | 17 | override fun afterTextChanged(s: Editable?) { 18 | afterTextChanged(s) 19 | } 20 | 21 | override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { 22 | beforeTextChanged(s, start, count, after) 23 | } 24 | 25 | override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { 26 | onTextChanged(s, start, before, count) 27 | } 28 | 29 | } 30 | 31 | fun View.visibleOrGone(visible: Boolean) { 32 | visibility = if (visible) View.VISIBLE else View.GONE 33 | } 34 | 35 | -------------------------------------------------------------------------------- /componentbridge/src/main/java/com/idisfkj/awesome/componentbridge/provider/BridgeProvider.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.componentbridge.provider 2 | 3 | import com.idisfkj.awesome.componentbridge.BridgeInterface 4 | import com.idisfkj.awesome.componentbridge.factory.Factory 5 | import com.idisfkj.awesome.componentbridge.store.BridgeStore 6 | 7 | /** 8 | * Created by idisfkj on 2019-08-29. 9 | * Email : idisfkj@gmail.com. 10 | */ 11 | class BridgeProvider(private val factory: Factory) { 12 | 13 | val bridgeStore = BridgeStore() 14 | 15 | companion object { 16 | private const val DEFAULT_KEY = "com.idisfkj.awesome.componentbridge" 17 | } 18 | 19 | fun get(key: String, bridgeClass: Class): T { 20 | var componentBridge = bridgeStore.get(key) 21 | if (bridgeClass.isInstance(componentBridge)) { 22 | @Suppress("UNCHECKED_CAST") 23 | return componentBridge as T 24 | } 25 | componentBridge = factory.create(bridgeClass) 26 | bridgeStore.put(key, componentBridge) 27 | return componentBridge 28 | } 29 | 30 | fun get(bridgeClass: Class): T = 31 | get(DEFAULT_KEY + "@" + bridgeClass.canonicalName, bridgeClass) 32 | } -------------------------------------------------------------------------------- /webview/src/main/java/com/idisfkj/awesome/webview/WebViewApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import com.idisfkj.awesome.webview.bridge.WebViewBridge 9 | import timber.log.Timber 10 | 11 | /** 12 | * Created by idisfkj on 2019-12-03. 13 | * Email: idisfkj@gmail.com. 14 | */ 15 | class WebViewApp : Application() { 16 | 17 | override fun onCreate() { 18 | super.onCreate() 19 | SPUtils.init(this) 20 | initTimber() 21 | initRouter() 22 | // register bridges 23 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 24 | .register(WebViewBridge::class.java) 25 | } 26 | 27 | private fun initTimber() { 28 | if (BuildConfig.DEBUG) { 29 | Timber.plant(Timber.DebugTree()) 30 | } 31 | } 32 | 33 | private fun initRouter() { 34 | if (BuildConfig.DEBUG) { 35 | ARouter.openLog() 36 | ARouter.openDebug() 37 | } 38 | ARouter.init(this) 39 | } 40 | } -------------------------------------------------------------------------------- /basic/src/main/java/com/idisfkj/awesome/basic/recyclerview/CommonRecyclerViewVH.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic.recyclerview 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import androidx.annotation.LayoutRes 7 | import androidx.databinding.ViewDataBinding 8 | import androidx.lifecycle.Lifecycle 9 | import com.idisfkj.awesome.basic.BaseRecyclerVM 10 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 11 | 12 | /** 13 | * Created by idisfkj on 2019-11-14. 14 | * Email: idisfkj@gmail.com. 15 | */ 16 | class CommonRecyclerViewVH : 17 | BaseRecyclerViewVH { 18 | 19 | constructor( 20 | view: ViewGroup, @LayoutRes layoutId: Int, 21 | vm: BaseRecyclerVM?, 22 | variableId: Int, 23 | outerLifecycle: Lifecycle? = null 24 | ) : super( 25 | LayoutInflater.from(view.context).inflate(layoutId, view, false), 26 | vm, 27 | variableId, 28 | outerLifecycle 29 | ) 30 | 31 | constructor( 32 | view: View, 33 | vm: BaseRecyclerVM?, 34 | variableId: Int, 35 | outerLifecycle: Lifecycle? = null 36 | ) : super(view, vm, variableId, outerLifecycle) 37 | 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/ui/main/MainViewPagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.ui.main 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.fragment.app.FragmentPagerAdapter 6 | import com.idisfkj.awesome.componentbridge.home.HomeBridgeInterface 7 | import com.idisfkj.awesome.componentbridge.notification.NotificationBridgeInterface 8 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 9 | import com.idisfkj.awesome.componentbridge.search.SearchBridgeInterface 10 | import com.idisfkj.awesome.componentbridge.user.UserBridgeInterface 11 | 12 | /** 13 | * Created by idisfkj on 2019-08-16. 14 | * Email : idisfkj@gmail.com. 15 | */ 16 | class MainViewPagerAdapter(fm: FragmentManager?) : FragmentPagerAdapter(fm) { 17 | 18 | override fun getItem(position: Int): Fragment = when (position) { 19 | 0 -> BridgeProviders.instance.getBridge(SearchBridgeInterface::class.java).getSearchFragment() 20 | 1 -> BridgeProviders.instance.getBridge(NotificationBridgeInterface::class.java) 21 | .getNotificationFragment() 22 | else -> BridgeProviders.instance.getBridge(UserBridgeInterface::class.java).getUserFragment() 23 | } 24 | 25 | override fun getCount(): Int = 3 26 | } -------------------------------------------------------------------------------- /repos/src/main/java/com/idisfkj/awesome/repos/ReposApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.repos 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import com.idisfkj.awesome.componentbridge.webview.DefaultWebViewBridge 9 | import timber.log.Timber 10 | 11 | /** 12 | * Created by idisfkj on 2019-11-19. 13 | * Email: idisfkj@gmail.com. 14 | */ 15 | class ReposApp : Application() { 16 | 17 | override fun onCreate() { 18 | super.onCreate() 19 | SPUtils.init(this) 20 | initTimber() 21 | initRouter() 22 | // register bridges 23 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 24 | .register(DefaultWebViewBridge::class.java) 25 | } 26 | 27 | private fun initTimber() { 28 | if (BuildConfig.DEBUG) { 29 | Timber.plant(Timber.DebugTree()) 30 | } 31 | } 32 | 33 | private fun initRouter() { 34 | if (BuildConfig.DEBUG) { 35 | ARouter.openLog() 36 | ARouter.openDebug() 37 | } 38 | ARouter.init(this) 39 | } 40 | } -------------------------------------------------------------------------------- /webview/src/main/java/com/idisfkj/awesome/webview/WebViewMainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview 2 | 3 | import androidx.lifecycle.Observer 4 | import com.idisfkj.awesome.basic.activity.BaseActivity 5 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 6 | import com.idisfkj.awesome.componentbridge.webview.WebViewBridgeInterface 7 | import com.idisfkj.awesome.webview.databinding.WebviewActivityWebviewMainBinding 8 | import com.idisfkj.awesome.webview.vm.WebViewMainVM 9 | 10 | /** 11 | * Created by idisfkj on 2019-12-03. 12 | * Email: idisfkj@gmail.com. 13 | */ 14 | class WebViewMainActivity : BaseActivity() { 15 | 16 | override fun getVariableId(): Int = BR.vm 17 | 18 | override fun getLayoutId(): Int = R.layout.webview_activity_webview_main 19 | 20 | override fun getViewModelInstance(): WebViewMainVM = WebViewMainVM() 21 | 22 | override fun getViewModelClass(): Class = WebViewMainVM::class.java 23 | 24 | override fun addObserver() { 25 | super.addObserver() 26 | viewModel.toPage.observe(this, Observer { 27 | BridgeProviders.instance.getBridge(WebViewBridgeInterface::class.java) 28 | .toWebViewActivity(this, it) 29 | }) 30 | } 31 | } -------------------------------------------------------------------------------- /repos/src/main/java/com/idisfkj/awesome/repos/adapter/ReposAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.repos.adapter 2 | 3 | import android.view.ViewGroup 4 | import androidx.databinding.ViewDataBinding 5 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 6 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewVH 7 | import com.idisfkj.awesome.basic.recyclerview.CommonRecyclerViewVH 8 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 9 | import com.idisfkj.awesome.common.model.ReposModel 10 | import com.idisfkj.awesome.repos.BR 11 | import com.idisfkj.awesome.repos.R 12 | import com.idisfkj.awesome.repos.databinding.ReposItemReposLayoutBinding 13 | import com.idisfkj.awesome.repos.vm.ReposVHVM 14 | 15 | /** 16 | * Created by idisfkj on 2019-11-20. 17 | * Email : idisfkj@gmail.com. 18 | */ 19 | class ReposAdapter : BaseRecyclerViewAdapter() { 20 | 21 | override fun onCreateViewHolder( 22 | parent: ViewGroup, 23 | viewType: Int 24 | ): BaseRecyclerViewVH { 25 | return CommonRecyclerViewVH( 26 | parent, 27 | R.layout.repos_item_repos_layout, 28 | ReposVHVM(parent.context), 29 | BR.vm 30 | ) 31 | } 32 | } -------------------------------------------------------------------------------- /repos/src/main/java/com/idisfkj/awesome/repos/vm/ReposVHVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.repos.vm 2 | 3 | import android.content.Context 4 | import androidx.lifecycle.MutableLiveData 5 | import com.alibaba.android.arouter.launcher.ARouter 6 | import com.idisfkj.awesome.basic.BaseRecyclerVM 7 | import com.idisfkj.awesome.common.PageDefault 8 | import com.idisfkj.awesome.common.ReposToWebView 9 | import com.idisfkj.awesome.common.ToPageStatus 10 | import com.idisfkj.awesome.common.model.ReposModel 11 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 12 | import com.idisfkj.awesome.componentbridge.webview.WebViewBridgeInterface 13 | 14 | /** 15 | * Created by idisfkj on 2019-11-20. 16 | * Email : idisfkj@gmail.com. 17 | */ 18 | class ReposVHVM(private val context: Context) : BaseRecyclerVM() { 19 | 20 | var data: ReposModel? = null 21 | 22 | override fun onBind(model: ReposModel?) { 23 | data = model 24 | } 25 | 26 | fun updateAtContent() = data?.run { 27 | val index = updated_at.indexOf("T") 28 | updated_at.substring(0, index) 29 | } ?: "" 30 | 31 | fun contentClick() { 32 | BridgeProviders.instance.getBridge(WebViewBridgeInterface::class.java) 33 | .toWebViewActivity(context, data?.html_url ?: "") 34 | } 35 | } -------------------------------------------------------------------------------- /basic/src/main/java/com/idisfkj/awesome/basic/recyclerview/BasePagedListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.basic.recyclerview 2 | 3 | import androidx.databinding.ViewDataBinding 4 | import androidx.paging.PagedListAdapter 5 | import androidx.recyclerview.widget.DiffUtil 6 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 7 | 8 | /** 9 | * support paged recyclerView adapter 10 | * Created by idisfkj on 2019-08-30. 11 | * Email : idisfkj@gmail.com. 12 | */ 13 | abstract class BasePagedListAdapter( 14 | callback: DiffUtil.ItemCallback = object : DiffUtil.ItemCallback() { 15 | override fun areItemsTheSame(oldItem: T, newItem: T): Boolean = 16 | areItemsTheSame(oldItem, newItem) 17 | 18 | override fun areContentsTheSame(oldItem: T, newItem: T): Boolean = 19 | areContentsTheSame(oldItem, newItem) 20 | 21 | }, 22 | areItemsTheSame: (oldItem: T, newItem: T) -> Boolean, 23 | areContentsTheSame: (oldItem: T, newItem: T) -> Boolean 24 | ) : PagedListAdapter>(callback) { 25 | 26 | override fun onBindViewHolder(holder: BaseRecyclerViewVH, position: Int) { 27 | holder.bind(getItem(position)) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /followers/src/main/java/com/idisfkj/awesome/followers/FollowersApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.followers 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import com.idisfkj.awesome.componentbridge.webview.DefaultWebViewBridge 9 | import timber.log.Timber 10 | 11 | /** 12 | * Created by idisfkj on 2019-11-21. 13 | * Email : idisfkj@gmail.com. 14 | */ 15 | class FollowersApp : Application() { 16 | 17 | override fun onCreate() { 18 | super.onCreate() 19 | SPUtils.init(this) 20 | initTimber() 21 | initRouter() 22 | // register bridges 23 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 24 | .register(DefaultWebViewBridge::class.java) 25 | } 26 | 27 | private fun initTimber() { 28 | if (BuildConfig.DEBUG) { 29 | Timber.plant(Timber.DebugTree()) 30 | } 31 | } 32 | 33 | private fun initRouter() { 34 | if (BuildConfig.DEBUG) { 35 | ARouter.openLog() 36 | ARouter.openDebug() 37 | } 38 | ARouter.init(this) 39 | } 40 | } -------------------------------------------------------------------------------- /following/src/main/java/com/idisfkj/awesome/following/FollowingApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.following 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import com.idisfkj.awesome.componentbridge.webview.DefaultWebViewBridge 9 | import timber.log.Timber 10 | 11 | /** 12 | * Created by idisfkj on 2019-11-26. 13 | * Email: idisfkj@gmail.com. 14 | */ 15 | class FollowingApp : Application() { 16 | 17 | override fun onCreate() { 18 | super.onCreate() 19 | SPUtils.init(this) 20 | initTimber() 21 | initRouter() 22 | // register bridges 23 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 24 | .register(DefaultWebViewBridge::class.java) 25 | } 26 | 27 | private fun initTimber() { 28 | if (BuildConfig.DEBUG) { 29 | Timber.plant(Timber.DebugTree()) 30 | } 31 | } 32 | 33 | private fun initRouter() { 34 | if (BuildConfig.DEBUG) { 35 | ARouter.openLog() 36 | ARouter.openDebug() 37 | } 38 | ARouter.init(this) 39 | } 40 | } -------------------------------------------------------------------------------- /notification/src/main/java/com/idisfkj/awesome/notification/NotificationApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import com.idisfkj.awesome.componentbridge.webview.DefaultWebViewBridge 9 | import timber.log.Timber 10 | 11 | /** 12 | * Created by idisfkj on 2019-11-27. 13 | * Email: idisfkj@gmail.com. 14 | */ 15 | class NotificationApp : Application() { 16 | 17 | override fun onCreate() { 18 | super.onCreate() 19 | SPUtils.init(this) 20 | initTimber() 21 | initRouter() 22 | // register bridges 23 | BridgeProviders.instance 24 | .register(DefaultAppBridge::class.java) 25 | .register(DefaultWebViewBridge::class.java) 26 | } 27 | 28 | private fun initTimber() { 29 | if (BuildConfig.DEBUG) { 30 | Timber.plant(Timber.DebugTree()) 31 | } 32 | } 33 | 34 | private fun initRouter() { 35 | if (BuildConfig.DEBUG) { 36 | ARouter.openLog() 37 | ARouter.openDebug() 38 | } 39 | ARouter.init(this) 40 | } 41 | } -------------------------------------------------------------------------------- /webview/src/main/java/com/idisfkj/awesome/webview/vm/WebViewMainVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.webview.vm 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.widget.SearchView 5 | import androidx.lifecycle.MutableLiveData 6 | import com.idisfkj.awesome.basic.BaseVM 7 | import com.idisfkj.awesome.common.PageDefault 8 | import com.idisfkj.awesome.common.ReposToWebView 9 | import com.idisfkj.awesome.common.ToPageStatus 10 | import com.idisfkj.awesome.common.live.SingleLiveEvent 11 | 12 | /** 13 | * Created by idisfkj on 2019-12-03. 14 | * Email: idisfkj@gmail.com. 15 | */ 16 | class WebViewMainVM : BaseVM() { 17 | 18 | val clearFocus = MutableLiveData(true) 19 | val toPage = SingleLiveEvent() 20 | 21 | override fun attach(savedInstanceState: Bundle?) { 22 | 23 | } 24 | 25 | fun setOnQueryTextListener() = object : SearchView.OnQueryTextListener { 26 | override fun onQueryTextSubmit(query: String?): Boolean { 27 | clearFocus.value = true 28 | searchSubmit(query) 29 | return true 30 | } 31 | 32 | override fun onQueryTextChange(newText: String?): Boolean { 33 | clearFocus.value = false 34 | return true 35 | } 36 | } 37 | 38 | private fun searchSubmit(query: String?) { 39 | toPage.value = query 40 | } 41 | } -------------------------------------------------------------------------------- /webview/src/main/res/layout/webview_activity_webview.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 15 | 16 | 22 | 23 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/idisfkj/awesome/github/ui/welcome/WelcomeVM.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.github.ui.welcome 2 | 3 | import android.os.Bundle 4 | import androidx.lifecycle.MutableLiveData 5 | import com.idisfkj.awesome.basic.BaseVM 6 | import com.idisfkj.awesome.common.PageDefault 7 | import com.idisfkj.awesome.common.ToPageStatus 8 | import com.idisfkj.awesome.common.WelcomeToLogin 9 | import com.idisfkj.awesome.common.WelcomeToMain 10 | import com.idisfkj.awesome.common.utils.CommonUtils 11 | import java.util.* 12 | 13 | /** 14 | * Created by idisfkj on 2019-08-13. 15 | * Email : idisfkj@gmail.com. 16 | */ 17 | class WelcomeVM : BaseVM() { 18 | 19 | val toPage = MutableLiveData(PageDefault) 20 | private var mTimer: Timer? = null 21 | 22 | override fun attach(savedInstanceState: Bundle?) { 23 | startDelay() 24 | } 25 | 26 | override fun onCleared() { 27 | super.onCleared() 28 | mTimer?.cancel() 29 | mTimer = null 30 | } 31 | 32 | private fun startDelay() { 33 | mTimer = Timer().apply { 34 | schedule(object : TimerTask() { 35 | override fun run() { 36 | mTimer = null 37 | toPage.postValue(if (CommonUtils.hasLogin()) WelcomeToMain else WelcomeToLogin) 38 | } 39 | 40 | }, 1500) 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /basic/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | apply plugin: 'kotlin-android' 6 | 7 | apply plugin: 'kotlin-kapt' 8 | 9 | android { 10 | compileSdkVersion Versions.target_sdk 11 | buildToolsVersion Versions.build_tools 12 | 13 | 14 | defaultConfig { 15 | minSdkVersion Versions.min_sdk 16 | targetSdkVersion Versions.target_sdk 17 | versionCode Versions.version_code 18 | versionName Versions.version_name 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | 22 | } 23 | 24 | dataBinding { 25 | enabled true 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | 35 | } 36 | 37 | dependencies { 38 | implementation project(':common') 39 | implementation Deps.kotlin_stdlib 40 | implementation Deps.kotlin_core 41 | 42 | api Deps.appcompat 43 | api Deps.material 44 | 45 | // architecture component 46 | api Deps.arch_lifecycle 47 | api Deps.arch_viewmodel 48 | api Deps.arch_runtime 49 | api Deps.paging_runtime 50 | 51 | //timber 52 | implementation Deps.timber 53 | } 54 | 55 | repositories { 56 | mavenCentral() 57 | } 58 | 59 | -------------------------------------------------------------------------------- /search/src/main/java/com/idisfkj/awesome/search/SearchApp.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.search 2 | 3 | import android.app.Application 4 | import com.alibaba.android.arouter.launcher.ARouter 5 | import com.idisfkj.awesome.common.utils.SPUtils 6 | import com.idisfkj.awesome.componentbridge.app.DefaultAppBridge 7 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 8 | import com.idisfkj.awesome.componentbridge.webview.DefaultWebViewBridge 9 | import com.idisfkj.awesome.repos.bridge.ReposBridge 10 | import timber.log.Timber 11 | 12 | /** 13 | * Created by idisfkj on 2019-12-01. 14 | * Email: idisfkj@gmail.com. 15 | */ 16 | class SearchApp : Application() { 17 | 18 | override fun onCreate() { 19 | super.onCreate() 20 | SPUtils.init(this) 21 | initTimber() 22 | initRouter() 23 | // register bridges 24 | BridgeProviders.instance.register(DefaultAppBridge::class.java) 25 | .register(ReposBridge::class.java) 26 | .register(DefaultWebViewBridge::class.java) 27 | } 28 | 29 | private fun initTimber() { 30 | if (BuildConfig.DEBUG) { 31 | Timber.plant(Timber.DebugTree()) 32 | } 33 | } 34 | 35 | private fun initRouter() { 36 | if (BuildConfig.DEBUG) { 37 | ARouter.openLog() 38 | ARouter.openDebug() 39 | } 40 | ARouter.init(this) 41 | } 42 | } -------------------------------------------------------------------------------- /network/src/main/java/com/idisfkj/awesome/network/GithubApiInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.network 2 | 3 | import android.text.TextUtils 4 | import com.idisfkj.awesome.componentbridge.app.AppBridgeInterface 5 | import com.idisfkj.awesome.componentbridge.provider.BridgeProviders 6 | import okhttp3.Interceptor 7 | import okhttp3.Response 8 | import timber.log.Timber 9 | 10 | /** 11 | * Created by idisfkj on 2019-08-29. 12 | * Email : idisfkj@gmail.com. 13 | */ 14 | class GithubApiInterceptor : Interceptor { 15 | 16 | override fun intercept(chain: Interceptor.Chain): Response { 17 | val request = chain.request() 18 | 19 | val appBridge = 20 | BridgeProviders.instance.getBridge(AppBridgeInterface::class.java) 21 | Timber.d("intercept url %s %s %s", request.url(), appBridge.getAuthorizationBasic(), appBridge.getAccessToken()) 22 | 23 | val builder = request.newBuilder() 24 | val authorization = 25 | if (!TextUtils.isEmpty(appBridge.getAuthorizationBasic())) "Basic " + appBridge.getAuthorizationBasic() 26 | else "token " + appBridge.getAccessToken() 27 | builder.addHeader("Authorization", authorization) 28 | val response = chain.proceed(builder.build()) 29 | Timber.d("intercept url %s, response %s ,code %d", request.url(), response.body().toString(), response.code()) 30 | return response 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/custom/LoadingView.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.custom 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import android.view.ViewGroup 8 | import android.widget.ImageView 9 | import android.widget.LinearLayout 10 | import com.bumptech.glide.Glide 11 | import com.bumptech.glide.request.RequestOptions 12 | import com.idisfkj.awesome.common.R 13 | import com.idisfkj.awesome.common.utils.CommonUtils 14 | 15 | /** 16 | * Descriptions: 全局Loading. 17 | * Created by idisfkj on 2019-11-13. 18 | * Email: idisfkj@gmail.com. 19 | */ 20 | class LoadingView @JvmOverloads constructor( 21 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 22 | ) : LinearLayout(context, attrs, defStyleAttr) { 23 | 24 | init { 25 | gravity = Gravity.CENTER 26 | layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) 27 | setBackgroundColor(Color.TRANSPARENT) 28 | addView(ImageView(context).apply { 29 | 30 | Glide.with(context).load(R.drawable.loading).apply(RequestOptions().apply { 31 | override( 32 | CommonUtils.dip2px(context, 64f), 33 | CommonUtils.dip2px(context, 64f) 34 | ).centerCrop() 35 | }).into(this) 36 | }) 37 | } 38 | } -------------------------------------------------------------------------------- /common/src/main/java/com/idisfkj/awesome/common/extensions/HttpExtensions.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.common.extensions 2 | 3 | import com.idisfkj.awesome.common.model.ResponseError 4 | import com.idisfkj.awesome.common.model.ResponseSuccess 5 | import kotlinx.coroutines.* 6 | import timber.log.Timber 7 | 8 | /** 9 | * Created by idisfkj on 2019-08-30. 10 | * Email : idisfkj@gmail.com. 11 | */ 12 | fun request( 13 | scope: CoroutineScope, 14 | callback: RequestCallback? = null, 15 | dispatcher: CoroutineDispatcher = Dispatchers.IO, 16 | handler: CoroutineExceptionHandler? = null, 17 | block: suspend CoroutineScope.() -> T 18 | ): Job = scope.launch(dispatcher) { 19 | try { 20 | val result = block() 21 | withContext(Dispatchers.Main) { 22 | callback?.onSuccess(ResponseSuccess(result)) 23 | } 24 | } catch (e: Exception) { 25 | e.printStackTrace() 26 | Timber.e("Http Request Exception message %s", e.message) 27 | withContext(Dispatchers.Main) { 28 | handler?.handleException(this.coroutineContext, e) 29 | callback?.onError(ResponseError(e)) 30 | // Timber.e("Http Request Exception code %d, message %s, response %s", e.code(), e.message(), e.response()) 31 | } 32 | } 33 | } 34 | 35 | interface RequestCallback { 36 | fun onSuccess(result: ResponseSuccess) 37 | fun onError(error: ResponseError) 38 | } 39 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | 23 | addLogin = true 24 | addHome = true 25 | addUser = true 26 | addRepos = true 27 | addFollowers = true 28 | addFollowing = true 29 | addNotification = true 30 | addSearch = true 31 | addWebView = true -------------------------------------------------------------------------------- /home/src/main/java/com/idisfkj/awesome/home/fragment/adapter/HomePagedListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.home.fragment.adapter 2 | 3 | import android.view.ViewGroup 4 | import androidx.databinding.ViewDataBinding 5 | import com.idisfkj.awesome.basic.recyclerview.BasePagedListAdapter 6 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewVH 7 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 8 | import com.idisfkj.awesome.common.model.UserModel 9 | import com.idisfkj.awesome.home.R 10 | import com.idisfkj.awesome.home.fragment.vh.HomeUserInfoVH 11 | import com.idisfkj.awesome.home.fragment.vm.HomeUserInfoVM 12 | 13 | /** 14 | * Created by idisfkj on 2019-09-02. 15 | * Email : idisfkj@gmail.com. 16 | */ 17 | class HomePagedListAdapter( 18 | areItemsTheSame: (oldItem: UserModel, newItem: UserModel) -> Boolean = { oldItem, newItem -> oldItem == newItem }, 19 | areContentsTheSame: (oldItem: UserModel, newItem: UserModel) -> Boolean = { oldItem, newItem -> oldItem.id == newItem.id } 20 | ) : BasePagedListAdapter( 21 | areItemsTheSame = areItemsTheSame, 22 | areContentsTheSame = areContentsTheSame 23 | ) { 24 | 25 | override fun onCreateViewHolder( 26 | parent: ViewGroup, 27 | viewType: Int 28 | ): BaseRecyclerViewVH { 29 | return HomeUserInfoVH(parent, R.layout.home_item_user_info_layout, HomeUserInfoVM()) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | apply plugin: 'kotlin-android' 6 | 7 | apply plugin: 'kotlin-kapt' 8 | 9 | android { 10 | compileSdkVersion Versions.target_sdk 11 | buildToolsVersion Versions.build_tools 12 | 13 | 14 | defaultConfig { 15 | minSdkVersion Versions.min_sdk 16 | targetSdkVersion Versions.target_sdk 17 | versionCode Versions.version_code 18 | versionName Versions.version_name 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | 22 | } 23 | 24 | dataBinding { 25 | enabled true 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | 35 | } 36 | 37 | dependencies { 38 | api Deps.kotlin_stdlib 39 | api Deps.kotlin_core 40 | 41 | api Deps.appcompat 42 | api Deps.constraint_layout 43 | api Deps.material 44 | api Deps.gson 45 | 46 | // architecture component 47 | api Deps.arch_lifecycle 48 | api Deps.arch_viewmodel 49 | api Deps.arch_runtime 50 | 51 | //timber 52 | api Deps.timber 53 | 54 | // glide 55 | implementation Deps.glide_runtime 56 | kapt Deps.glide_compiler 57 | } 58 | 59 | repositories { 60 | mavenCentral() 61 | } 62 | -------------------------------------------------------------------------------- /notification/src/main/java/com/idisfkj/awesome/notification/adapter/NotificationAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idisfkj.awesome.notification.adapter 2 | 3 | import android.view.ViewGroup 4 | import androidx.databinding.ViewDataBinding 5 | import androidx.lifecycle.Lifecycle 6 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewAdapter 7 | import com.idisfkj.awesome.basic.recyclerview.BaseRecyclerViewVH 8 | import com.idisfkj.awesome.basic.recyclerview.CommonRecyclerViewVH 9 | import com.idisfkj.awesome.common.model.BaseRecyclerViewModel 10 | import com.idisfkj.awesome.notification.BR 11 | import com.idisfkj.awesome.notification.R 12 | import com.idisfkj.awesome.notification.repository.NotificationRepository 13 | import com.idisfkj.awesome.notification.vm.NotificationVHVM 14 | 15 | /** 16 | * Created by idisfkj on 2019-11-28. 17 | * Email : idisfkj@gmail.com. 18 | */ 19 | class NotificationAdapter( 20 | private val repository: NotificationRepository, 21 | private val outerLifecycle: Lifecycle 22 | ) : BaseRecyclerViewAdapter(outerLifecycle) { 23 | 24 | override fun onCreateViewHolder( 25 | parent: ViewGroup, 26 | viewType: Int 27 | ): BaseRecyclerViewVH { 28 | return CommonRecyclerViewVH( 29 | parent, 30 | R.layout.notify_item_notification_layout, 31 | NotificationVHVM(parent.context, repository), 32 | BR.vm, 33 | outerLifecycle 34 | ) 35 | } 36 | } --------------------------------------------------------------------------------