├── .gitignore
├── .idea
├── assetWizardSettings.xml
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── copyright
│ └── horaciocome1.xml
├── dictionaries
│ └── horaciocome1.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── navEditor.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── google-services.json
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── io
│ │ └── github
│ │ └── horaciocome1
│ │ └── reaque
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ │ └── io
│ │ │ └── github
│ │ │ └── horaciocome1
│ │ │ └── reaque
│ │ │ ├── data
│ │ │ ├── Database.kt
│ │ │ ├── bookmarks
│ │ │ │ ├── BookmarksInterface.kt
│ │ │ │ ├── BookmarksRepository.kt
│ │ │ │ └── BookmarksService.kt
│ │ │ ├── configurations
│ │ │ │ ├── ConfigurationsInterface.kt
│ │ │ │ ├── ConfigurationsRepository.kt
│ │ │ │ └── ConfigurationsService.kt
│ │ │ ├── feed
│ │ │ │ ├── FeedInterface.kt
│ │ │ │ ├── FeedRepository.kt
│ │ │ │ └── FeedService.kt
│ │ │ ├── posts
│ │ │ │ ├── Post.kt
│ │ │ │ ├── PostsInterface.kt
│ │ │ │ ├── PostsRepository.kt
│ │ │ │ └── PostsService.kt
│ │ │ ├── ratings
│ │ │ │ ├── RatingsInterface.kt
│ │ │ │ ├── RatingsRepository.kt
│ │ │ │ └── RatingsService.kt
│ │ │ ├── readings
│ │ │ │ ├── ReadingsInterface.kt
│ │ │ │ ├── ReadingsRepository.kt
│ │ │ │ └── ReadingsService.kt
│ │ │ ├── shares
│ │ │ │ ├── SharesInterface.kt
│ │ │ │ ├── SharesRepository.kt
│ │ │ │ └── SharesService.kt
│ │ │ ├── storage
│ │ │ │ ├── StorageRepository.kt
│ │ │ │ └── StorageService.kt
│ │ │ ├── subscriptions
│ │ │ │ ├── SubscriptionsInterface.kt
│ │ │ │ ├── SubscriptionsRepository.kt
│ │ │ │ └── SubscriptionsService.kt
│ │ │ ├── topics
│ │ │ │ ├── Topic.kt
│ │ │ │ ├── TopicsRepository.kt
│ │ │ │ └── TopicsService.kt
│ │ │ └── users
│ │ │ │ ├── User.kt
│ │ │ │ ├── UsersInterface.kt
│ │ │ │ ├── UsersRepository.kt
│ │ │ │ └── UsersService.kt
│ │ │ ├── services
│ │ │ └── MyFirebaseMessagingService.kt
│ │ │ ├── ui
│ │ │ ├── MainActivity.kt
│ │ │ ├── explore
│ │ │ │ ├── ExploreFragment.kt
│ │ │ │ ├── ExploreViewModel.kt
│ │ │ │ ├── ExploreViewModelFactory.kt
│ │ │ │ └── TopicsAdapter.kt
│ │ │ ├── feed
│ │ │ │ ├── FeedFragment.kt
│ │ │ │ ├── FeedViewModel.kt
│ │ │ │ └── FeedViewModelFactory.kt
│ │ │ ├── more
│ │ │ │ ├── MoreFragment.kt
│ │ │ │ ├── MoreViewModel.kt
│ │ │ │ └── MoreViewModelFactory.kt
│ │ │ ├── posts
│ │ │ │ ├── PostsAdapter.kt
│ │ │ │ ├── PostsFragment.kt
│ │ │ │ ├── PostsViewModel.kt
│ │ │ │ ├── PostsViewModelFactory.kt
│ │ │ │ ├── create
│ │ │ │ │ ├── CreatePostFragment.kt
│ │ │ │ │ ├── CreatePostViewModel.kt
│ │ │ │ │ └── CreatePostViewModelFactory.kt
│ │ │ │ └── read
│ │ │ │ │ ├── ReadPostFragment.kt
│ │ │ │ │ ├── ReadPostViewModel.kt
│ │ │ │ │ ├── ReadPostViewModelFactory.kt
│ │ │ │ │ └── SetRatingFragment.kt
│ │ │ ├── sign_in
│ │ │ │ ├── SignInFragment.kt
│ │ │ │ ├── SignInViewModel.kt
│ │ │ │ └── SignInViewModelFactory.kt
│ │ │ └── users
│ │ │ │ ├── UsersAdapter.kt
│ │ │ │ ├── UsersFragment.kt
│ │ │ │ ├── UsersViewModel.kt
│ │ │ │ ├── UsersViewModelFactory.kt
│ │ │ │ ├── profile
│ │ │ │ ├── UserProfileFragment.kt
│ │ │ │ ├── UserProfileViewModel.kt
│ │ │ │ └── UserProfileViewModelFactory.kt
│ │ │ │ └── update
│ │ │ │ ├── UpdateUserFragment.kt
│ │ │ │ ├── UpdateUserViewModel.kt
│ │ │ │ └── UpdateUserViewModelFactory.kt
│ │ │ └── util
│ │ │ ├── BindingAdapters.kt
│ │ │ ├── Constants.kt
│ │ │ ├── DateUtils.kt
│ │ │ ├── DocumentSnapshotUtils.kt
│ │ │ ├── DomainUtils.kt
│ │ │ ├── DynamicLinksUtils.kt
│ │ │ ├── InjectorUtils.kt
│ │ │ ├── ObservableViewModel.kt
│ │ │ ├── OnFocusChangeListener.kt
│ │ │ └── QuerySnapshotUtils.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── background_all_corners_rounded_secondary.xml
│ │ ├── background_bottomsheet.xml
│ │ ├── background_bottomsheet_stroke.xml
│ │ ├── background_shadow_bottom_to_top.xml
│ │ ├── background_splash.xml
│ │ ├── baseline_bookmark_18.xml
│ │ ├── color_bottom_navigation.xml
│ │ ├── color_side_navigation.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_undraw_camera_mg5h.xml
│ │ ├── ic_undraw_ideas_s70l.xml
│ │ ├── ic_undraw_reading_0re1.xml
│ │ ├── outline_access_time_18.xml
│ │ ├── outline_add_18.xml
│ │ ├── outline_add_photo_alternate_18.xml
│ │ ├── outline_arrow_forward_18.xml
│ │ ├── outline_bookmark_border_18.xml
│ │ ├── outline_bookmarks_18.xml
│ │ ├── outline_close_24.xml
│ │ ├── outline_cloud_download_18.xml
│ │ ├── outline_drag_handle_24.xml
│ │ ├── outline_edit_18.xml
│ │ ├── outline_exit_to_app_18.xml
│ │ ├── outline_explore_24.xml
│ │ ├── outline_feedback_18.xml
│ │ ├── outline_info_18.xml
│ │ ├── outline_info_24.xml
│ │ ├── outline_library_books_18.xml
│ │ ├── outline_location_on_18.xml
│ │ ├── outline_more_horiz_24.xml
│ │ ├── outline_people_outline_18.xml
│ │ ├── outline_share_18.xml
│ │ ├── outline_short_text_18.xml
│ │ ├── outline_subject_18.xml
│ │ └── outline_whatshot_24.xml
│ │ ├── font
│ │ ├── roboto.xml
│ │ ├── roboto_light.xml
│ │ ├── roboto_medium.xml
│ │ └── roboto_thin.xml
│ │ ├── layout-land
│ │ └── activity_main.xml
│ │ ├── layout-v21
│ │ ├── fragment_explore.xml
│ │ ├── fragment_user_profile.xml
│ │ ├── item_topic.xml
│ │ ├── layout_read_my_rating_section.xml
│ │ ├── layout_read_post_content_section.xml
│ │ └── layout_read_post_footer_section.xml
│ │ ├── layout-w600dp
│ │ ├── layout_create_post_select_topic_section.xml
│ │ ├── layout_explore_topics_section.xml
│ │ ├── layout_feed_list.xml
│ │ ├── layout_posts_list.xml
│ │ └── layout_users_list.xml
│ │ ├── layout-w900dp
│ │ ├── layout_create_post_select_topic_section.xml
│ │ ├── layout_explore_topics_section.xml
│ │ ├── layout_feed_list.xml
│ │ ├── layout_posts_list.xml
│ │ └── layout_users_list.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── fragment_create_post.xml
│ │ ├── fragment_explore.xml
│ │ ├── fragment_feed.xml
│ │ ├── fragment_more.xml
│ │ ├── fragment_posts.xml
│ │ ├── fragment_read_post.xml
│ │ ├── fragment_set_rating.xml
│ │ ├── fragment_sign_in.xml
│ │ ├── fragment_update_user.xml
│ │ ├── fragment_user_profile.xml
│ │ ├── fragment_users.xml
│ │ ├── item_post.xml
│ │ ├── item_suggestion.xml
│ │ ├── item_topic.xml
│ │ ├── item_user.xml
│ │ ├── layout_appbar.xml
│ │ ├── layout_create_post_actions_section.xml
│ │ ├── layout_create_post_content_section.xml
│ │ ├── layout_create_post_loading_screen.xml
│ │ ├── layout_create_post_select_topic_section.xml
│ │ ├── layout_explore_suggestions_section.xml
│ │ ├── layout_explore_topics_section.xml
│ │ ├── layout_feed_list.xml
│ │ ├── layout_header.xml
│ │ ├── layout_more_about_section.xml
│ │ ├── layout_more_actions_section.xml
│ │ ├── layout_more_footer_section.xml
│ │ ├── layout_more_session_section.xml
│ │ ├── layout_more_updates_section.xml
│ │ ├── layout_more_user_section.xml
│ │ ├── layout_posts_list.xml
│ │ ├── layout_read_my_rating_section.xml
│ │ ├── layout_read_post_content_section.xml
│ │ ├── layout_read_post_footer_section.xml
│ │ ├── layout_update_user_content.xml
│ │ ├── layout_update_user_loading_screen.xml
│ │ ├── layout_user_profile_actions_section.xml
│ │ ├── layout_user_profile_details_section.xml
│ │ ├── layout_user_profile_header_section.xml
│ │ └── layout_users_list.xml
│ │ ├── menu
│ │ ├── main.xml
│ │ └── navigation.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── navigation
│ │ └── navigation.xml
│ │ ├── values-night
│ │ ├── colors.xml
│ │ └── styles.xml
│ │ ├── values-pt
│ │ └── strings.xml
│ │ ├── values-v21
│ │ └── dimens.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── font_certs.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── preloaded_fonts.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── backup_descriptor.xml
│ └── test
│ └── java
│ └── io
│ └── github
│ └── horaciocome1
│ └── reaque
│ └── ExampleUnitTest.kt
├── build.gradle
├── docs
├── DONATE.md
├── LICENSE
├── PRIVACY_POLICY.md
├── TERMS_AND_CONDITIONS.md
└── diagrams
│ ├── reaque-architecture.jpg
│ └── use_case.png
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshots
├── logo.png
├── mock1.png
├── mock2.png
├── mock3.png
├── screen1.png
├── screen2.png
├── screen3.png
├── screen4.png
├── screen5.png
├── screen6.png
├── screen7.png
└── screen8.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches/build_file_checksums.ser
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | .DS_Store
9 | /build
10 | /captures
11 | .externalNativeBuild
12 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/copyright/horaciocome1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/dictionaries/horaciocome1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | comé
5 | flávio
6 | horácio
7 | júnior
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "122712633760",
4 | "firebase_url": "https://reaque.firebaseio.com",
5 | "project_id": "reaque",
6 | "storage_bucket": "reaque.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:122712633760:android:282dab5331ca358d",
12 | "android_client_info": {
13 | "package_name": "io.github.horaciocome1.reaque"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "122712633760-kb5oics5qg5135lgqrig7tubkvk2c6h6.apps.googleusercontent.com",
19 | "client_type": 1,
20 | "android_info": {
21 | "package_name": "io.github.horaciocome1.reaque",
22 | "certificate_hash": "aa220d6f23b8cdcdd4a9fec2368cf166834b15f3"
23 | }
24 | },
25 | {
26 | "client_id": "122712633760-pm82l3ctb5pep0njfgmhgjv945c7j6cp.apps.googleusercontent.com",
27 | "client_type": 1,
28 | "android_info": {
29 | "package_name": "io.github.horaciocome1.reaque",
30 | "certificate_hash": "5c79a18f386941942c4f5c6df4502319063de1f7"
31 | }
32 | },
33 | {
34 | "client_id": "122712633760-66sqghv6p3dldgp9d37ps3li4ar37c6a.apps.googleusercontent.com",
35 | "client_type": 3
36 | }
37 | ],
38 | "api_key": [
39 | {
40 | "current_key": "AIzaSyBsyD3INiI46fNPu0nbj53Qcrs5ab1-Ih4"
41 | }
42 | ],
43 | "services": {
44 | "appinvite_service": {
45 | "other_platform_oauth_client": [
46 | {
47 | "client_id": "122712633760-66sqghv6p3dldgp9d37ps3li4ar37c6a.apps.googleusercontent.com",
48 | "client_type": 3
49 | }
50 | ]
51 | }
52 | }
53 | }
54 | ],
55 | "configuration_version": "1"
56 | }
--------------------------------------------------------------------------------
/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 namePostsFragment 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 namePostsFragment.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | # Firebase auth
24 | -keepattributes Signature
25 | -keepattributes *Annotation*
--------------------------------------------------------------------------------
/app/src/androidTest/java/io/github/horaciocome1/reaque/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque
17 |
18 | import androidx.test.InstrumentationRegistry
19 | import androidx.test.runner.AndroidJUnit4
20 | import org.junit.Assert.assertEquals
21 | import org.junit.Test
22 | import org.junit.runner.RunWith
23 |
24 | /**
25 | * Instrumented test, which will execute on an Android device.
26 | *
27 | * See [testing documentation](http://d.android.com/tools/testing).
28 | */
29 | @RunWith(AndroidJUnit4::class)
30 | class ExampleInstrumentedTest {
31 | @Test
32 | fun useAppContext() {
33 | // Context of the app under test.
34 | val appContext = InstrumentationRegistry.getTargetContext()
35 | assertEquals("io.github.horaciocome1.reaque", appContext.packageName)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/bookmarks/BookmarksInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.bookmarks
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.google.android.gms.tasks.Task
5 | import io.github.horaciocome1.reaque.data.posts.Post
6 |
7 | interface BookmarksInterface {
8 |
9 | fun bookmark(post: Post, onCompleteListener: (Task?) -> Unit)
10 |
11 | fun unBookmark(post: Post, onCompleteListener: (Task?) -> Unit)
12 |
13 | fun get(): LiveData>
14 |
15 | fun isBookmarked(post: Post): LiveData
16 |
17 | fun hasBookmarks(): LiveData
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/bookmarks/BookmarksRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.bookmarks
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | class BookmarksRepository private constructor(
7 | private val service: BookmarksService
8 | ) : BookmarksInterface {
9 |
10 | override fun bookmark(post: Post, onCompleteListener: (Task?) -> Unit) =
11 | service.bookmark(post, onCompleteListener)
12 |
13 | override fun unBookmark(post: Post, onCompleteListener: (Task?) -> Unit) =
14 | service.unBookmark(post, onCompleteListener)
15 |
16 | override fun get() = service.get()
17 |
18 | override fun isBookmarked(post: Post) = service.isBookmarked(post)
19 |
20 | override fun hasBookmarks() = service.hasBookmarks()
21 |
22 | companion object {
23 |
24 | @Volatile
25 | private var instance: BookmarksRepository? = null
26 |
27 | fun getInstance(service: BookmarksService) = instance ?: synchronized(this) {
28 | instance ?: BookmarksRepository(service)
29 | .also {
30 | instance = it
31 | }
32 | }
33 |
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/configurations/ConfigurationsInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.configurations
2 |
3 | import androidx.lifecycle.LiveData
4 |
5 | interface ConfigurationsInterface {
6 |
7 | fun isUpdateAvailable(): LiveData
8 |
9 | fun getLatestVersionName(): LiveData
10 |
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/configurations/ConfigurationsRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.configurations
2 |
3 | class ConfigurationsRepository private constructor(
4 | private val service: ConfigurationsService
5 | ) : ConfigurationsInterface {
6 |
7 | override fun isUpdateAvailable() = service.isUpdateAvailable()
8 |
9 | override fun getLatestVersionName() = service.getLatestVersionName()
10 |
11 | companion object {
12 |
13 | @Volatile
14 | private var instance: ConfigurationsRepository? = null
15 |
16 | fun getInstance(service: ConfigurationsService) = instance ?: synchronized(this) {
17 | instance ?: ConfigurationsRepository(service)
18 | .also {
19 | instance = it
20 | }
21 | }
22 |
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/configurations/ConfigurationsService.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.configurations
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import com.google.firebase.auth.FirebaseAuth
6 | import com.google.firebase.firestore.FirebaseFirestore
7 | import io.github.horaciocome1.reaque.BuildConfig
8 |
9 | class ConfigurationsService : ConfigurationsInterface {
10 |
11 | private val versionCode: Int by lazy {
12 | BuildConfig.VERSION_CODE
13 | }
14 |
15 | val auth: FirebaseAuth by lazy {
16 | FirebaseAuth.getInstance()
17 | }
18 |
19 | private val db: FirebaseFirestore by lazy {
20 | FirebaseFirestore.getInstance()
21 | }
22 |
23 | private val isUpdateAvailable: MutableLiveData by lazy {
24 | MutableLiveData()
25 | .apply {
26 | value = false
27 | }
28 | }
29 |
30 | private val latestVersionName: MutableLiveData by lazy {
31 | MutableLiveData()
32 | .apply {
33 | value = ""
34 | }
35 | }
36 |
37 | override fun isUpdateAvailable(): LiveData {
38 | isUpdateAvailable.value = false
39 | db.document("configurations/default")
40 | .addSnapshotListener { snapshot, exception ->
41 | if (
42 | exception == null
43 | && snapshot != null
44 | && snapshot.contains("version_code")
45 | )
46 | isUpdateAvailable.value = versionCode < snapshot["version_code"].toString()
47 | .toInt()
48 | }
49 | return isUpdateAvailable
50 | }
51 |
52 | override fun getLatestVersionName(): LiveData {
53 | db.document("configurations/default")
54 | .addSnapshotListener { snapshot, exception ->
55 | if (
56 | exception == null
57 | && snapshot != null
58 | && snapshot.contains("version_name")
59 | )
60 | latestVersionName.value = snapshot["version_name"].toString()
61 | }
62 | return latestVersionName
63 | }
64 |
65 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/feed/FeedInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.feed
2 |
3 | import androidx.lifecycle.LiveData
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | interface FeedInterface {
7 |
8 | fun get(): LiveData>
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/feed/FeedRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.feed
2 |
3 | class FeedRepository private constructor(
4 | private val service: FeedService
5 | ) : FeedInterface {
6 |
7 | override fun get() = service.get()
8 |
9 | companion object {
10 |
11 | @Volatile
12 | private var instance: FeedRepository? = null
13 |
14 | fun getInstance(service: FeedService) = instance ?: synchronized(this) {
15 | instance ?: FeedRepository(service)
16 | .also {
17 | instance = it
18 | }
19 | }
20 |
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/feed/FeedService.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.feed
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import com.google.firebase.auth.FirebaseAuth
6 | import com.google.firebase.firestore.FirebaseFirestore
7 | import com.google.firebase.firestore.Query
8 | import io.github.horaciocome1.reaque.data.posts.Post
9 | import io.github.horaciocome1.reaque.util.posts
10 |
11 | class FeedService : FeedInterface {
12 |
13 | private val db: FirebaseFirestore by lazy {
14 | FirebaseFirestore.getInstance()
15 | }
16 |
17 | private val auth: FirebaseAuth by lazy {
18 | FirebaseAuth.getInstance()
19 | }
20 |
21 | private var _posts = mutableListOf()
22 |
23 | private val posts: MutableLiveData> by lazy {
24 | MutableLiveData>().apply {
25 | value = mutableListOf()
26 | }
27 | }
28 |
29 | override fun get(): LiveData> {
30 | if (auth.currentUser == null)
31 | auth.addAuthStateListener {
32 | if (
33 | _posts.isEmpty()
34 | && it.currentUser != null
35 | && _posts.isEmpty()
36 | )
37 | getFeed()
38 | }
39 | else if (_posts.isEmpty())
40 | getFeed()
41 | return posts
42 | }
43 |
44 | private fun getFeed() {
45 | db.collection("users/${auth.currentUser!!.uid}/feed")
46 | .orderBy("timestamp", Query.Direction.DESCENDING)
47 | .limit(100)
48 | .get()
49 | .addOnSuccessListener {
50 | if (it != null) {
51 | _posts = it.posts
52 | posts.value = _posts
53 | }
54 | }
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/posts/Post.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.posts
17 |
18 | import com.google.firebase.Timestamp
19 | import io.github.horaciocome1.reaque.data.topics.Topic
20 | import io.github.horaciocome1.reaque.data.users.User
21 | import io.github.horaciocome1.reaque.util.string
22 |
23 | data class Post(var id: String) {
24 |
25 | var title = ""
26 | var date = ""
27 | var user = User("")
28 | var pic = ""
29 | var message = ""
30 | var topic = Topic("")
31 | var timestamp = Timestamp.now()
32 | set(value) {
33 | date = value.string
34 | field = value
35 | }
36 | var score: Float = 1f - (1f / timestamp.seconds)
37 | var rating = 0f
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/posts/PostsInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.posts
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.google.android.gms.tasks.Task
5 | import io.github.horaciocome1.reaque.data.topics.Topic
6 | import io.github.horaciocome1.reaque.data.users.User
7 |
8 | interface PostsInterface {
9 |
10 | fun create(post: Post, onCompleteListener: (Task?) -> Unit)
11 |
12 | fun get(post: Post): LiveData
13 |
14 | fun get(user: User): LiveData>
15 |
16 | fun get(topic: Topic): LiveData>
17 |
18 | fun getTop10(): LiveData>
19 |
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/posts/PostsRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.posts
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.topics.Topic
5 | import io.github.horaciocome1.reaque.data.users.User
6 |
7 | class PostsRepository private constructor(
8 | private val service: PostsService
9 | ) : PostsInterface {
10 |
11 | override fun create(post: Post, onCompleteListener: (Task?) -> Unit) =
12 | service.create(post, onCompleteListener)
13 |
14 | override fun get(post: Post) = service.get(post)
15 |
16 | override fun get(user: User) = service.get(user)
17 |
18 | override fun get(topic: Topic) = service.get(topic)
19 |
20 | override fun getTop10() = service.getTop10()
21 |
22 | companion object {
23 |
24 | @Volatile
25 | private var instance: PostsRepository? = null
26 |
27 | fun getInstance(service: PostsService) = instance ?: synchronized(this) {
28 | instance ?: PostsRepository(service)
29 | .also {
30 | instance = it
31 | }
32 | }
33 |
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/ratings/RatingsInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.ratings
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.google.android.gms.tasks.Task
5 | import io.github.horaciocome1.reaque.data.posts.Post
6 |
7 | interface RatingsInterface {
8 |
9 | fun set(post: Post, value: Int, onCompleteListener: (Task?) -> Unit)
10 |
11 | fun get(post: Post): LiveData
12 |
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/ratings/RatingsRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.ratings
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | class RatingsRepository private constructor(private val service: RatingsService) : RatingsInterface {
7 |
8 | override fun set(post: Post, value: Int, onCompleteListener: (Task?) -> Unit) =
9 | service.set(post, value, onCompleteListener)
10 |
11 | override fun get(post: Post) = service.get(post)
12 |
13 | companion object {
14 |
15 | @Volatile
16 | private var instance: RatingsRepository? = null
17 |
18 | fun getInstance(service: RatingsService) = instance ?: synchronized(this) {
19 | instance ?: RatingsRepository(service)
20 | .also {
21 | instance = it
22 | }
23 | }
24 |
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/ratings/RatingsService.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.ratings
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import com.google.android.gms.tasks.Task
6 | import com.google.firebase.auth.FirebaseAuth
7 | import com.google.firebase.firestore.FirebaseFirestore
8 | import com.google.firebase.firestore.SetOptions
9 | import io.github.horaciocome1.reaque.data.posts.Post
10 | import io.github.horaciocome1.reaque.util.map
11 | import io.github.horaciocome1.reaque.util.user
12 |
13 | class RatingsService : RatingsInterface {
14 |
15 | private val db: FirebaseFirestore by lazy {
16 | FirebaseFirestore.getInstance()
17 | }
18 |
19 | private val auth: FirebaseAuth by lazy {
20 | FirebaseAuth.getInstance()
21 | }
22 |
23 | private val rating: MutableLiveData by lazy {
24 | MutableLiveData().apply {
25 | value = 0
26 | }
27 | }
28 |
29 | override fun set(post: Post, value: Int, onCompleteListener: (Task?) -> Unit) {
30 | if (
31 | post.id.isNotBlank()
32 | && value >= 1
33 | && value <= 5
34 | && auth.currentUser != null
35 | ) {
36 | val data = auth.currentUser!!.user.map
37 | .plus("value" to value)
38 | .plus(
39 | "post" to mapOf(
40 | "id" to post.id
41 | )
42 | )
43 | db.document(
44 | "posts/${post.id}" +
45 | "/ratings/${auth.currentUser!!.uid}"
46 | )
47 | .set(data, SetOptions.merge())
48 | .addOnCompleteListener(onCompleteListener)
49 | }
50 | }
51 |
52 | override fun get(post: Post): LiveData {
53 | rating.value = 0
54 | if (post.id.isNotBlank() && auth.currentUser != null)
55 | db.document(
56 | "posts/${post.id}" +
57 | "/ratings/${auth.currentUser!!.uid}"
58 | )
59 | .addSnapshotListener { snapshot, exception ->
60 | if (
61 | exception == null
62 | && snapshot != null
63 | && snapshot.contains("value")
64 | )
65 | rating.value = snapshot["value"]
66 | .toString()
67 | .toInt()
68 | }
69 | return rating
70 | }
71 |
72 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/readings/ReadingsInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.readings
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | interface ReadingsInterface {
7 |
8 | fun read(post: Post, onCompleteListener: (Task?) -> Unit)
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/readings/ReadingsRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.readings
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | class ReadingsRepository private constructor(
7 | private val service: ReadingsService
8 | ) : ReadingsInterface {
9 |
10 | override fun read(post: Post, onCompleteListener: (Task?) -> Unit) = service.read(post, onCompleteListener)
11 |
12 | companion object {
13 |
14 | @Volatile
15 | private var instance: ReadingsRepository? = null
16 |
17 | fun getInstance(service: ReadingsService) = instance ?: synchronized(this) {
18 | instance ?: ReadingsRepository(service)
19 | .also {
20 | instance = it
21 | }
22 | }
23 |
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/readings/ReadingsService.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.readings
2 |
3 | import com.google.android.gms.tasks.Task
4 | import com.google.firebase.auth.FirebaseAuth
5 | import com.google.firebase.firestore.FieldValue
6 | import com.google.firebase.firestore.FirebaseFirestore
7 | import com.google.firebase.firestore.SetOptions
8 | import io.github.horaciocome1.reaque.data.posts.Post
9 | import io.github.horaciocome1.reaque.util.mapSimple
10 |
11 | class ReadingsService : ReadingsInterface {
12 |
13 | private val db: FirebaseFirestore by lazy {
14 | FirebaseFirestore.getInstance()
15 | }
16 |
17 | private val auth: FirebaseAuth by lazy {
18 | FirebaseAuth.getInstance()
19 | }
20 |
21 | private val increment: Map by lazy {
22 | val increment = FieldValue.increment(1)
23 | mapOf("readings" to increment)
24 | }
25 |
26 | override fun read(post: Post, onCompleteListener: (Task?) -> Unit) {
27 | if (
28 | post.id.isNotBlank()
29 | && auth.currentUser != null
30 | ) {
31 | val readingRef = db.document(
32 | "users/${auth.currentUser!!.uid}" +
33 | "/readings/${post.id}"
34 | )
35 | val postRef = db.document("posts/${post.id}")
36 | db.runBatch {
37 | it.set(readingRef, post.mapSimple)
38 | it.set(postRef, increment, SetOptions.merge())
39 | }.addOnCompleteListener(onCompleteListener)
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/shares/SharesInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.shares
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | interface SharesInterface {
7 |
8 | fun share(post: Post, onCompleteListener: (Task?) -> Unit)
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/shares/SharesRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.shares
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 |
6 | class SharesRepository private constructor(
7 | private val service: SharesService
8 | ) : SharesInterface {
9 |
10 | override fun share(post: Post, onCompleteListener: (Task?) -> Unit) = service.share(post, onCompleteListener)
11 |
12 | companion object {
13 |
14 | @Volatile
15 | private var instance: SharesRepository? = null
16 |
17 | fun getInstance(service: SharesService) = instance ?: synchronized(this) {
18 | instance ?: SharesRepository(service)
19 | .also {
20 | instance = it
21 | }
22 | }
23 |
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/shares/SharesService.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.shares
2 |
3 | import com.google.android.gms.tasks.Task
4 | import com.google.firebase.auth.FirebaseAuth
5 | import com.google.firebase.firestore.FieldValue
6 | import com.google.firebase.firestore.FirebaseFirestore
7 | import com.google.firebase.firestore.SetOptions
8 | import io.github.horaciocome1.reaque.data.posts.Post
9 | import io.github.horaciocome1.reaque.util.mapSimple
10 |
11 | class SharesService : SharesInterface {
12 |
13 | private val db: FirebaseFirestore by lazy {
14 | FirebaseFirestore.getInstance()
15 | }
16 |
17 | private val auth: FirebaseAuth by lazy {
18 | FirebaseAuth.getInstance()
19 | }
20 |
21 | private val increment: Map by lazy {
22 | val increment = FieldValue.increment(1)
23 | mapOf("shares" to increment)
24 | }
25 |
26 | override fun share(post: Post, onCompleteListener: (Task?) -> Unit) {
27 | if (post.id.isNotBlank() && auth.currentUser != null) {
28 | val readingRef = db.document(
29 | "users/${auth.currentUser!!.uid}" +
30 | "/shares/${post.id}"
31 | )
32 | val postRef = db.document("posts/${post.id}")
33 | db.runBatch {
34 | it.set(readingRef, post.mapSimple)
35 | it.set(postRef, increment, SetOptions.merge())
36 | }.addOnCompleteListener(onCompleteListener)
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/storage/StorageRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.storage
17 |
18 | import android.net.Uri
19 | import io.github.horaciocome1.reaque.data.topics.Topic
20 |
21 | class StorageRepository private constructor(
22 | private val webservice: StorageService
23 | ) {
24 |
25 | fun uploadImage(imageUri: Uri, topic: Topic, onSuccessListener: (Uri?) -> Unit) =
26 | webservice.upload(imageUri, topic, onSuccessListener)
27 |
28 | companion object {
29 |
30 | @Volatile
31 | private var instance: StorageRepository? = null
32 |
33 | fun getInstance(webservice: StorageService) = instance ?: synchronized(this) {
34 | instance ?: StorageRepository(webservice)
35 | .also {
36 | instance = it
37 | }
38 | }
39 |
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/storage/StorageService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.storage
17 |
18 | import android.net.Uri
19 | import com.google.android.gms.tasks.Continuation
20 | import com.google.android.gms.tasks.Task
21 | import com.google.firebase.storage.FirebaseStorage
22 | import com.google.firebase.storage.UploadTask
23 | import io.github.horaciocome1.reaque.data.topics.Topic
24 |
25 | class StorageService {
26 |
27 | private val storage: FirebaseStorage by lazy {
28 | FirebaseStorage.getInstance()
29 | }
30 |
31 | fun upload(imageUri: Uri, topic: Topic, onSuccessListener: (Uri?) -> Unit) {
32 | if (
33 | imageUri != Uri.EMPTY
34 | && topic.id.isNotBlank()
35 | ) {
36 | val path = "images/${topic.id}/${imageUri.lastPathSegment}"
37 | val ref = storage.reference.child(path)
38 | ref.putFile(imageUri)
39 | .continueWithTask(Continuation> { task ->
40 | if (!task.isSuccessful)
41 | task.exception?.let {
42 | throw it
43 | }
44 | return@Continuation ref.downloadUrl
45 | })
46 | .addOnSuccessListener(onSuccessListener)
47 | }
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/subscriptions/SubscriptionsInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.subscriptions
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.google.android.gms.tasks.Task
5 | import io.github.horaciocome1.reaque.data.users.User
6 |
7 | interface SubscriptionsInterface {
8 |
9 | fun subscribe(user: User, onCompleteListener: (Task?) -> Unit)
10 |
11 | fun unSubscribe(user: User, onCompleteListener: (Task?) -> Unit)
12 |
13 | fun getSubscriptions(user: User): LiveData>
14 |
15 | fun getSubscribers(user: User): LiveData>
16 |
17 | fun amSubscribedTo(user: User): LiveData
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/subscriptions/SubscriptionsRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.subscriptions
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.users.User
5 |
6 | class SubscriptionsRepository private constructor(
7 | private val service: SubscriptionsService
8 | ) : SubscriptionsInterface {
9 |
10 | override fun subscribe(user: User, onCompleteListener: (Task?) -> Unit) =
11 | service.subscribe(user, onCompleteListener)
12 |
13 | override fun unSubscribe(user: User, onCompleteListener: (Task?) -> Unit) =
14 | service.unSubscribe(user, onCompleteListener)
15 |
16 | override fun getSubscriptions(user: User) = service.getSubscriptions(user)
17 |
18 | override fun getSubscribers(user: User) = service.getSubscribers(user)
19 |
20 | override fun amSubscribedTo(user: User) = service.amSubscribedTo(user)
21 |
22 | companion object {
23 |
24 | private var instance: SubscriptionsRepository? = null
25 |
26 | fun getInstance(service: SubscriptionsService) = instance ?: synchronized(this) {
27 | instance ?: SubscriptionsRepository(service)
28 | .also {
29 | instance = it
30 | }
31 | }
32 |
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/topics/Topic.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.topics
17 |
18 | data class Topic(var id: String) {
19 |
20 | var title = ""
21 | var pic = ""
22 |
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/topics/TopicsRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.topics
17 |
18 | import androidx.lifecycle.LiveData
19 |
20 | class TopicsRepository private constructor(
21 | service: TopicsService
22 | ) {
23 |
24 | val notEmptyTopics: LiveData> by lazy {
25 | service.notEmptyTopics
26 | }
27 |
28 | val topics: LiveData> by lazy {
29 | service.topics
30 | }
31 |
32 | companion object {
33 |
34 | @Volatile
35 | private var instance: TopicsRepository? = null
36 |
37 | fun getInstance(topicsService: TopicsService) = instance ?: synchronized(this) {
38 | instance ?: TopicsRepository(topicsService)
39 | .also {
40 | instance = it
41 | }
42 | }
43 |
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/topics/TopicsService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.topics
17 |
18 | import androidx.lifecycle.MutableLiveData
19 | import com.google.firebase.firestore.CollectionReference
20 | import com.google.firebase.firestore.FirebaseFirestore
21 | import com.google.firebase.firestore.Query
22 | import io.github.horaciocome1.reaque.util.topics
23 |
24 | class TopicsService {
25 |
26 | private val ref: CollectionReference by lazy {
27 | FirebaseFirestore.getInstance().collection("topics")
28 | }
29 |
30 | private var _notEmptyTopics = mutableListOf()
31 |
32 | val notEmptyTopics = MutableLiveData>()
33 | get() {
34 | if (_notEmptyTopics.isEmpty())
35 | ref.whereGreaterThan("score", 0)
36 | .orderBy("score", Query.Direction.DESCENDING)
37 | .get()
38 | .addOnSuccessListener {
39 | if (it != null) {
40 | _notEmptyTopics = it.topics
41 | field.value = _notEmptyTopics
42 | }
43 | }
44 | return field
45 | }
46 |
47 | private var _topics = mutableListOf()
48 |
49 | val topics = MutableLiveData>()
50 | get() {
51 | if (_topics.isEmpty())
52 | ref.orderBy("title", Query.Direction.ASCENDING)
53 | .get()
54 | .addOnSuccessListener {
55 | if (it != null) {
56 | _topics = it.topics
57 | field.value = _topics
58 | }
59 | }
60 | return field
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/users/User.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.data.users
17 |
18 | import io.github.horaciocome1.reaque.util.string
19 |
20 | data class User(var id: String) {
21 |
22 | var name = ""
23 | var bio = ""
24 | var pic = ""
25 | var address = ""
26 | var email = ""
27 | var since = ""
28 | var timestamp = com.google.firebase.Timestamp.now()
29 | set(value) {
30 | since = value.string
31 | field = value
32 | }
33 | var topTopic = ""
34 | var posts = "0"
35 | var subscribers = "0"
36 | var subscriptions = "0"
37 | var score = 0f
38 |
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/users/UsersInterface.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.users
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.google.android.gms.tasks.Task
5 | import io.github.horaciocome1.reaque.data.topics.Topic
6 |
7 | interface UsersInterface {
8 |
9 | fun update(user: User, onCompleteListener: (Task?) -> Unit)
10 |
11 | fun get(user: User): LiveData
12 |
13 | fun get(topic: Topic): LiveData>
14 |
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/data/users/UsersRepository.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.data.users
2 |
3 | import com.google.android.gms.tasks.Task
4 | import io.github.horaciocome1.reaque.data.topics.Topic
5 |
6 | class UsersRepository private constructor(
7 | private val service: UsersService
8 | ) : UsersInterface {
9 |
10 | override fun update(user: User, onCompleteListener: (Task?) -> Unit) =
11 | service.update(user, onCompleteListener)
12 |
13 | override fun get(user: User) = service.get(user)
14 |
15 | override fun get(topic: Topic) = service.get(topic)
16 |
17 | companion object {
18 |
19 | @Volatile
20 | private var instance: UsersRepository? = null
21 |
22 | fun getInstance(service: UsersService) = instance ?: synchronized(this) {
23 | instance ?: UsersRepository(service)
24 | .also {
25 | instance = it
26 | }
27 | }
28 |
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/explore/ExploreFragment.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.explore
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.Observer
9 | import androidx.lifecycle.ViewModelProviders
10 | import io.github.horaciocome1.reaque.databinding.FragmentExploreBinding
11 | import io.github.horaciocome1.reaque.util.InjectorUtils
12 | import io.github.horaciocome1.simplerecyclerviewtouchlistener.addOnItemClickListener
13 | import io.github.horaciocome1.simplerecyclerviewtouchlistener.addOnItemLongPressListener
14 | import kotlinx.android.synthetic.main.layout_explore_suggestions_section.*
15 | import kotlinx.android.synthetic.main.layout_explore_topics_section.*
16 |
17 | class ExploreFragment : Fragment() {
18 |
19 | lateinit var binding: FragmentExploreBinding
20 |
21 | private val viewModel: ExploreViewModel by lazy {
22 | val factory = InjectorUtils.exploreViewModelFactory
23 | ViewModelProviders.of(this, factory)[ExploreViewModel::class.java]
24 | }
25 |
26 | override fun onCreateView(
27 | inflater: LayoutInflater,
28 | container: ViewGroup?,
29 | savedInstanceState: Bundle?
30 | ): View? {
31 | binding = FragmentExploreBinding.inflate(inflater, container, false)
32 | return binding.root
33 | }
34 |
35 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
36 | super.onViewCreated(view, savedInstanceState)
37 | posts_recyclerview.addOnItemClickListener(viewModel.onItemPostClickListener)
38 | topics_recyclerview.addOnItemClickListener(viewModel.onItemTopicClickListener)
39 | topics_recyclerview.addOnItemLongPressListener(viewModel.onItemTopicLongPressListener)
40 | }
41 |
42 | override fun onStart() {
43 | super.onStart()
44 | viewModel.notEmptyTopics
45 | .observe(this, Observer {
46 | binding.viewmodel = viewModel.setTopics(it)
47 | })
48 | viewModel.top10
49 | .observe(this, Observer {
50 | binding.viewmodel = viewModel.setPosts(it)
51 | })
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/explore/ExploreViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.explore
2 |
3 | import android.view.View
4 | import androidx.lifecycle.ViewModel
5 | import androidx.navigation.findNavController
6 | import io.github.horaciocome1.reaque.data.posts.Post
7 | import io.github.horaciocome1.reaque.data.posts.PostsRepository
8 | import io.github.horaciocome1.reaque.data.topics.Topic
9 | import io.github.horaciocome1.reaque.data.topics.TopicsRepository
10 | import io.github.horaciocome1.reaque.util.Constants
11 |
12 | class ExploreViewModel(topicsRepository: TopicsRepository, postsRepository: PostsRepository) : ViewModel() {
13 |
14 | var topics: List = mutableListOf()
15 |
16 | var posts: List = mutableListOf()
17 |
18 | val notEmptyTopics = topicsRepository.notEmptyTopics
19 |
20 | val top10 = postsRepository.getTop10()
21 |
22 | val onItemPostClickListener: (View, Int) -> Unit = { view, position ->
23 | if (posts.isNotEmpty()) {
24 | val directions = ExploreFragmentDirections
25 | .actionOpenReadPostFromExplore(posts[position].id)
26 | view.findNavController()
27 | .navigate(directions)
28 | }
29 | }
30 |
31 | val onItemTopicClickListener: (View, Int) -> Unit = { view, position ->
32 | if (posts.isNotEmpty()) {
33 | val directions = ExploreFragmentDirections
34 | .actionOpenPostsFromExplore(topics[position].id, Constants.TOPIC_POSTS_REQUEST)
35 | view.findNavController()
36 | .navigate(directions)
37 | }
38 | }
39 |
40 | val onItemTopicLongPressListener: (View, Int) -> Unit = { view, position ->
41 | if (posts.isNotEmpty()) {
42 | val directions = ExploreFragmentDirections
43 | .actionOpenUsersFromExplore(topics[position].id, Constants.TOPIC_USERS_REQUEST)
44 | view.findNavController()
45 | .navigate(directions)
46 | }
47 | }
48 |
49 | fun setTopics(topics: List): ExploreViewModel {
50 | this.topics = topics
51 | return this
52 | }
53 |
54 | fun setPosts(posts: List): ExploreViewModel {
55 | this.posts = posts
56 | return this
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/explore/ExploreViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.explore
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.posts.PostsRepository
6 | import io.github.horaciocome1.reaque.data.topics.TopicsRepository
7 |
8 | class ExploreViewModelFactory(
9 | private val topicsRepository: TopicsRepository,
10 | private val postsRepository: PostsRepository
11 | ) : ViewModelProvider.NewInstanceFactory() {
12 |
13 | @Suppress("UNCHECKED_CAST")
14 | override fun create(modelClass: Class) =
15 | ExploreViewModel(topicsRepository, postsRepository) as T
16 |
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/explore/TopicsAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.ui.explore
17 |
18 | import android.view.LayoutInflater
19 | import android.view.View
20 | import android.view.ViewGroup
21 | import androidx.recyclerview.widget.RecyclerView
22 | import io.github.horaciocome1.reaque.data.topics.Topic
23 | import io.github.horaciocome1.reaque.databinding.ItemTopicBinding
24 |
25 | class TopicsAdapter(private val list: List) :
26 | RecyclerView.Adapter() {
27 |
28 | private lateinit var binding: ItemTopicBinding
29 |
30 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
31 | val inflater = LayoutInflater.from(parent.context)
32 | binding = ItemTopicBinding.inflate(inflater, parent, false)
33 | return ViewHolder(binding.root)
34 | }
35 |
36 | override fun getItemCount() = list.size
37 |
38 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
39 | binding.topic = list[position]
40 | }
41 |
42 | class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
43 |
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/feed/FeedFragment.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.feed
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.Observer
9 | import androidx.lifecycle.ViewModelProviders
10 | import io.github.horaciocome1.reaque.databinding.FragmentFeedBinding
11 | import io.github.horaciocome1.reaque.util.InjectorUtils
12 | import io.github.horaciocome1.simplerecyclerviewtouchlistener.addOnItemClickListener
13 | import kotlinx.android.synthetic.main.layout_feed_list.*
14 |
15 | class FeedFragment : Fragment() {
16 |
17 | lateinit var binding: FragmentFeedBinding
18 |
19 | private val viewModel: FeedViewModel by lazy {
20 | val factory = InjectorUtils.feedViewModelFactory
21 | ViewModelProviders.of(this, factory)[FeedViewModel::class.java]
22 | }
23 |
24 | override fun onCreateView(
25 | inflater: LayoutInflater,
26 | container: ViewGroup?,
27 | savedInstanceState: Bundle?
28 | ): View? {
29 | binding = FragmentFeedBinding.inflate(inflater, container, false)
30 | return binding.root
31 | }
32 |
33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
34 | super.onViewCreated(view, savedInstanceState)
35 | posts_recyclerview.addOnItemClickListener(viewModel.onItemClickListener)
36 | }
37 |
38 | override fun onStart() {
39 | super.onStart()
40 | viewModel.feed
41 | .observe(this, Observer {
42 | binding.viewmodel = viewModel.setPosts(it)
43 | })
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/feed/FeedViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.feed
2 |
3 | import android.view.View
4 | import androidx.lifecycle.ViewModel
5 | import androidx.navigation.findNavController
6 | import io.github.horaciocome1.reaque.data.feed.FeedRepository
7 | import io.github.horaciocome1.reaque.data.posts.Post
8 |
9 | class FeedViewModel(repository: FeedRepository) : ViewModel() {
10 |
11 | var posts: List = mutableListOf()
12 |
13 | val feed = repository.get()
14 |
15 | val onItemClickListener: (View, Int) -> Unit = { view, position ->
16 | if (posts.isNotEmpty()) {
17 | val directions = FeedFragmentDirections
18 | .actionOpenReadPostFromFeed(posts[position].id)
19 | view.findNavController()
20 | .navigate(directions)
21 | }
22 | }
23 |
24 | fun setPosts(posts: List): FeedViewModel {
25 | this.posts = posts
26 | return this
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/feed/FeedViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.feed
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.feed.FeedRepository
6 |
7 | class FeedViewModelFactory(private val repository: FeedRepository) :
8 | ViewModelProvider.NewInstanceFactory() {
9 |
10 | @Suppress("UNCHECKED_CAST")
11 | override fun create(modelClass: Class): T = FeedViewModel(repository) as T
12 |
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/more/MoreViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.ui.more
17 |
18 | import androidx.lifecycle.ViewModel
19 | import androidx.lifecycle.ViewModelProvider
20 | import io.github.horaciocome1.reaque.data.bookmarks.BookmarksRepository
21 | import io.github.horaciocome1.reaque.data.configurations.ConfigurationsRepository
22 |
23 | class MoreViewModelFactory(
24 | private val bookmarksRepository: BookmarksRepository,
25 | private val configurationsRepository: ConfigurationsRepository
26 | ) : ViewModelProvider.NewInstanceFactory() {
27 |
28 | @Suppress("UNCHECKED_CAST")
29 | override fun create(modelClass: Class) =
30 | MoreViewModel(bookmarksRepository, configurationsRepository) as T
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/posts/PostsAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.ui.posts
17 |
18 | import android.view.LayoutInflater
19 | import android.view.View
20 | import android.view.ViewGroup
21 | import androidx.recyclerview.widget.RecyclerView
22 | import io.github.horaciocome1.reaque.data.posts.Post
23 | import io.github.horaciocome1.reaque.databinding.ItemPostBinding
24 | import io.github.horaciocome1.reaque.databinding.ItemSuggestionBinding
25 |
26 | class PostsAdapter(private val list: List) : RecyclerView.Adapter() {
27 |
28 | private lateinit var binding: ItemPostBinding
29 |
30 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
31 | val inflater = LayoutInflater.from(parent.context)
32 | binding = ItemPostBinding.inflate(inflater, parent, false)
33 | return ViewHolder(binding.root)
34 | }
35 |
36 | override fun getItemCount() = list.size
37 |
38 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
39 | binding.post = list[position]
40 | }
41 |
42 | class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
43 |
44 | class SuggestionsAdapter(private val list: List) :
45 | RecyclerView.Adapter() {
46 |
47 | private lateinit var binding: ItemSuggestionBinding
48 |
49 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
50 | val inflater = LayoutInflater.from(parent.context)
51 | binding = ItemSuggestionBinding.inflate(inflater, parent, false)
52 | return ViewHolder(binding.root)
53 | }
54 |
55 | override fun getItemCount() = list.size
56 |
57 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
58 | binding.post = list[position]
59 | }
60 |
61 | class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
62 |
63 | }
64 |
65 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/posts/PostsFragment.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.posts
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.Observer
9 | import androidx.lifecycle.ViewModelProviders
10 | import io.github.horaciocome1.reaque.databinding.FragmentPostsBinding
11 | import io.github.horaciocome1.reaque.util.InjectorUtils
12 | import io.github.horaciocome1.simplerecyclerviewtouchlistener.addOnItemClickListener
13 | import kotlinx.android.synthetic.main.layout_posts_list.*
14 |
15 | class PostsFragment : Fragment() {
16 |
17 | private lateinit var binding: FragmentPostsBinding
18 |
19 | private val viewModel: PostsViewModel by lazy {
20 | val factory = InjectorUtils.postsViewModelFactory
21 | ViewModelProviders.of(this, factory)[PostsViewModel::class.java]
22 | }
23 |
24 | override fun onCreateView(
25 | inflater: LayoutInflater,
26 | container: ViewGroup?,
27 | savedInstanceState: Bundle?
28 | ): View? {
29 | binding = FragmentPostsBinding.inflate(inflater, container, false)
30 | return binding.root
31 | }
32 |
33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
34 | super.onViewCreated(view, savedInstanceState)
35 | posts_recyclerview.addOnItemClickListener(viewModel.onItemClickListener)
36 | }
37 |
38 | override fun onStart() {
39 | super.onStart()
40 | arguments?.let { bundle ->
41 | val args = PostsFragmentArgs.fromBundle(bundle)
42 | viewModel.get(args.parentId, args.requestId)
43 | .observe(this, Observer {
44 | binding.viewmodel = viewModel.setPosts(it)
45 | })
46 | }
47 | }
48 |
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/posts/PostsViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.posts
2 |
3 | import android.view.View
4 | import androidx.lifecycle.LiveData
5 | import androidx.lifecycle.ViewModel
6 | import androidx.navigation.findNavController
7 | import io.github.horaciocome1.reaque.data.bookmarks.BookmarksRepository
8 | import io.github.horaciocome1.reaque.data.posts.Post
9 | import io.github.horaciocome1.reaque.data.posts.PostsRepository
10 | import io.github.horaciocome1.reaque.data.topics.Topic
11 | import io.github.horaciocome1.reaque.data.users.User
12 | import io.github.horaciocome1.reaque.util.Constants
13 |
14 | class PostsViewModel(
15 | private val postsRepository: PostsRepository,
16 | private val bookmarksRepository: BookmarksRepository
17 | ) : ViewModel() {
18 |
19 | var posts: List = mutableListOf()
20 |
21 | val onItemClickListener: (View, Int) -> Unit = { view, position ->
22 | if (posts.isNotEmpty()) {
23 | val directions = PostsFragmentDirections
24 | .actionOpenReadPostFromPosts(posts[position].id)
25 | view.findNavController()
26 | .navigate(directions)
27 | }
28 | }
29 |
30 | fun setPosts(posts: List): PostsViewModel {
31 | this.posts = posts
32 | return this
33 | }
34 |
35 |
36 | fun get(parentId: String, requestId: String): LiveData> {
37 | return when (requestId) {
38 | Constants.TOPIC_POSTS_REQUEST -> postsRepository.get((Topic(parentId)))
39 | Constants.USER_POSTS_REQUEST -> postsRepository.get((User(parentId)))
40 | else -> bookmarksRepository.get()
41 | }
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/posts/PostsViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.posts
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.bookmarks.BookmarksRepository
6 | import io.github.horaciocome1.reaque.data.posts.PostsRepository
7 |
8 | class PostsViewModelFactory(
9 | private val postsRepository: PostsRepository,
10 | private val bookmarksRepository: BookmarksRepository
11 | ) : ViewModelProvider.NewInstanceFactory() {
12 |
13 | @Suppress("UNCHECKED_CAST")
14 | override fun create(modelClass: Class) =
15 | PostsViewModel(postsRepository, bookmarksRepository) as T
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/posts/create/CreatePostViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.posts.create
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.posts.PostsRepository
6 | import io.github.horaciocome1.reaque.data.storage.StorageRepository
7 | import io.github.horaciocome1.reaque.data.topics.TopicsRepository
8 |
9 | class CreatePostViewModelFactory(
10 | private val postsRepository: PostsRepository,
11 | private val topicsRepository: TopicsRepository,
12 | private val storageRepository: StorageRepository
13 | ) : ViewModelProvider.NewInstanceFactory() {
14 |
15 | @Suppress("UNCHECKED_CAST")
16 | override fun create(modelClass: Class) = CreatePostViewModel(
17 | topicsRepository,
18 | postsRepository,
19 | storageRepository
20 | ) as T
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/posts/read/ReadPostViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.posts.read
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.bookmarks.BookmarksRepository
6 | import io.github.horaciocome1.reaque.data.posts.PostsRepository
7 | import io.github.horaciocome1.reaque.data.ratings.RatingsRepository
8 | import io.github.horaciocome1.reaque.data.readings.ReadingsRepository
9 | import io.github.horaciocome1.reaque.data.shares.SharesRepository
10 |
11 | class ReadPostViewModelFactory(
12 | private val postsRepository: PostsRepository,
13 | private val readingsRepository: ReadingsRepository,
14 | private val sharesRepository: SharesRepository,
15 | private val ratingsRepository: RatingsRepository,
16 | private val bookmarksRepository: BookmarksRepository
17 | ) : ViewModelProvider.NewInstanceFactory() {
18 |
19 | @Suppress("UNCHECKED_CAST")
20 | override fun create(modelClass: Class) = ReadPostViewModel(
21 | postsRepository,
22 | readingsRepository,
23 | sharesRepository,
24 | ratingsRepository,
25 | bookmarksRepository
26 | ) as T
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/sign_in/SignInViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.sign_in
2 |
3 | import androidx.lifecycle.ViewModel
4 | import com.google.android.gms.auth.api.signin.GoogleSignIn
5 | import com.google.android.gms.auth.api.signin.GoogleSignInAccount
6 | import com.google.android.gms.auth.api.signin.GoogleSignInOptions
7 | import com.google.firebase.auth.FirebaseAuth
8 | import com.google.firebase.auth.GoogleAuthProvider
9 | import io.github.horaciocome1.reaque.R
10 | import io.github.horaciocome1.reaque.ui.MainActivity
11 | import io.github.horaciocome1.reaque.util.Constants
12 |
13 | class SignInViewModel : ViewModel() {
14 |
15 | private val auth: FirebaseAuth by lazy {
16 | FirebaseAuth.getInstance()
17 | }
18 |
19 | fun signInWithGoogle(fragment: SignInFragment) {
20 | val activity = fragment.activity
21 | if (activity is MainActivity) {
22 | val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
23 | .requestIdToken(activity.getString(R.string.default_web_client_id))
24 | .requestEmail()
25 | .build()
26 | val googleSignInClient = GoogleSignIn.getClient(activity, gso)
27 | fragment.startActivityForResult(
28 | googleSignInClient?.signInIntent,
29 | Constants.GOOGLE_SIGN_IN_REQUEST_CODE
30 | )
31 | }
32 | }
33 |
34 | fun firebaseAuthWithGoogle(
35 | account: GoogleSignInAccount,
36 | listener: (Any) -> Unit
37 | ) {
38 | val credential = GoogleAuthProvider.getCredential(account.idToken, null)
39 | auth.signInWithCredential(credential)
40 | .addOnSuccessListener(listener)
41 | .addOnFailureListener(listener)
42 | }
43 |
44 |
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/sign_in/SignInViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.sign_in
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 |
6 | class SignInViewModelFactory : ViewModelProvider.NewInstanceFactory() {
7 |
8 | @Suppress("UNCHECKED_CAST")
9 | override fun create(modelClass: Class) = SignInViewModel() as T
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/UsersAdapter.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.recyclerview.widget.RecyclerView
7 | import io.github.horaciocome1.reaque.data.users.User
8 | import io.github.horaciocome1.reaque.databinding.ItemUserBinding
9 |
10 | class UsersAdapter(private val list: List) : RecyclerView.Adapter() {
11 |
12 | private lateinit var binding: ItemUserBinding
13 |
14 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
15 | val inflater = LayoutInflater.from(parent.context)
16 | binding = ItemUserBinding.inflate(inflater, parent, false)
17 | return ViewHolder(binding.root)
18 | }
19 |
20 | override fun getItemCount() = list.size
21 |
22 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
23 | binding.user = list[position]
24 | }
25 |
26 | class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
27 |
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/UsersFragment.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.Observer
9 | import androidx.lifecycle.ViewModelProviders
10 | import io.github.horaciocome1.reaque.databinding.FragmentUsersBinding
11 | import io.github.horaciocome1.reaque.util.InjectorUtils
12 | import io.github.horaciocome1.simplerecyclerviewtouchlistener.addOnItemClickListener
13 | import kotlinx.android.synthetic.main.layout_users_list.*
14 |
15 | class UsersFragment : Fragment() {
16 |
17 | private lateinit var binding: FragmentUsersBinding
18 |
19 | private val viewModel: UsersViewModel by lazy {
20 | val factory = InjectorUtils.usersViewModelFactory
21 | ViewModelProviders.of(this, factory)[UsersViewModel::class.java]
22 | }
23 |
24 | override fun onCreateView(
25 | inflater: LayoutInflater,
26 | container: ViewGroup?,
27 | savedInstanceState: Bundle?
28 | ): View? {
29 | binding = FragmentUsersBinding.inflate(inflater, container, false)
30 | return binding.root
31 | }
32 |
33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
34 | super.onViewCreated(view, savedInstanceState)
35 | users_recyclerview.addOnItemClickListener(viewModel.onItemClickListener)
36 | }
37 |
38 | override fun onStart() {
39 | super.onStart()
40 | arguments?.let { bundle ->
41 | val args = UsersFragmentArgs.fromBundle(bundle)
42 | viewModel.get(args.parentId, args.requestId)
43 | .observe(this, Observer {
44 | binding.viewmodel = viewModel.setUsers(it)
45 | })
46 | }
47 | }
48 |
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/UsersViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users
2 |
3 | import android.view.View
4 | import androidx.lifecycle.LiveData
5 | import androidx.lifecycle.ViewModel
6 | import androidx.navigation.findNavController
7 | import io.github.horaciocome1.reaque.data.subscriptions.SubscriptionsRepository
8 | import io.github.horaciocome1.reaque.data.topics.Topic
9 | import io.github.horaciocome1.reaque.data.users.User
10 | import io.github.horaciocome1.reaque.data.users.UsersRepository
11 | import io.github.horaciocome1.reaque.util.Constants
12 |
13 | class UsersViewModel(
14 | private val usersRepository: UsersRepository,
15 | private val subscriptionsRepository: SubscriptionsRepository
16 | ) : ViewModel() {
17 |
18 | var users: List = mutableListOf()
19 |
20 | val onItemClickListener: (View, Int) -> Unit = { view, position ->
21 | if (users.isNotEmpty()) {
22 | val directions = UsersFragmentDirections.actionOpenUserProfileFromUsers(users[position].id)
23 | view.findNavController().navigate(directions)
24 | }
25 | }
26 |
27 | fun setUsers(users: List): UsersViewModel {
28 | this.users = users
29 | return this
30 | }
31 |
32 | fun get(parentId: String, requestId: String): LiveData> {
33 | return when (requestId) {
34 | Constants.SUBSCRIPTIONS_REQUEST -> subscriptionsRepository.getSubscriptions(User(parentId))
35 | Constants.SUBSCRIBERS_REQUEST -> subscriptionsRepository.getSubscribers(User(parentId))
36 | else -> usersRepository.get(Topic(parentId))
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/UsersViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.subscriptions.SubscriptionsRepository
6 | import io.github.horaciocome1.reaque.data.users.UsersRepository
7 |
8 | class UsersViewModelFactory(
9 | private val usersRepository: UsersRepository,
10 | private val subscriptionsRepository: SubscriptionsRepository
11 | ) : ViewModelProvider.NewInstanceFactory() {
12 |
13 | @Suppress("UNCHECKED_CAST")
14 | override fun create(modelClass: Class) =
15 | UsersViewModel(usersRepository, subscriptionsRepository) as T
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/profile/UserProfileViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users.profile
2 |
3 | import android.view.View
4 | import androidx.lifecycle.ViewModel
5 | import androidx.navigation.findNavController
6 | import io.github.horaciocome1.reaque.data.subscriptions.SubscriptionsRepository
7 | import io.github.horaciocome1.reaque.data.users.User
8 | import io.github.horaciocome1.reaque.data.users.UsersRepository
9 | import io.github.horaciocome1.reaque.util.Constants
10 |
11 | class UserProfileViewModel(
12 | private val usersRepository: UsersRepository,
13 | private val subscriptionsRepository: SubscriptionsRepository
14 | ) : ViewModel() {
15 |
16 | fun get(user: User) = usersRepository.get(user)
17 |
18 | fun subscribe(view: View, user: User) {
19 | view.isEnabled = false
20 | subscriptionsRepository.subscribe(user) {
21 | view.visibility = View.GONE
22 | }
23 | }
24 |
25 | fun unSubscribe(view: View, user: User) {
26 | view.isEnabled = false
27 | subscriptionsRepository.unSubscribe(user) {
28 | view.visibility = View.GONE
29 | }
30 | }
31 |
32 | fun amSubscribedTo(user: User) = subscriptionsRepository.amSubscribedTo(user)
33 |
34 | fun openSubscribers(view: View, user: User) {
35 | if (user.subscribers.isNotBlank() && user.subscribers != "0") {
36 | val directions = UserProfileFragmentDirections
37 | .actionOpenUsersFromUserProfile(user.id, Constants.SUBSCRIBERS_REQUEST)
38 | view.findNavController()
39 | .navigate(directions)
40 | }
41 | }
42 |
43 | fun openSubscriptions(view: View, user: User) {
44 | if (user.subscriptions.isNotBlank() && user.subscriptions != "0") {
45 | val directions = UserProfileFragmentDirections
46 | .actionOpenUsersFromUserProfile(user.id, Constants.SUBSCRIPTIONS_REQUEST)
47 | view.findNavController()
48 | .navigate(directions)
49 | }
50 | }
51 |
52 | fun openPosts(view: View, user: User) {
53 | if (user.posts.isNotBlank() && user.posts != "0") {
54 | val directions = UserProfileFragmentDirections
55 | .actionOpenPostsFromUserProfile(user.id, Constants.USER_POSTS_REQUEST)
56 | view.findNavController()
57 | .navigate(directions)
58 | }
59 | }
60 |
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/profile/UserProfileViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users.profile
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.subscriptions.SubscriptionsRepository
6 | import io.github.horaciocome1.reaque.data.users.UsersRepository
7 |
8 | class UserProfileViewModelFactory(
9 | private val usersRepository: UsersRepository,
10 | private val subscriptionsRepository: SubscriptionsRepository
11 | ) : ViewModelProvider.NewInstanceFactory() {
12 |
13 | @Suppress("UNCHECKED_CAST")
14 | override fun create(modelClass: Class) =
15 | UserProfileViewModel(usersRepository, subscriptionsRepository) as T
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/update/UpdateUserViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users.update
2 |
3 | import android.view.View
4 | import androidx.databinding.Bindable
5 | import androidx.lifecycle.MutableLiveData
6 | import androidx.navigation.findNavController
7 | import io.github.horaciocome1.reaque.data.users.User
8 | import io.github.horaciocome1.reaque.data.users.UsersRepository
9 | import io.github.horaciocome1.reaque.util.ObservableViewModel
10 |
11 | class UpdateUserViewModel(private val repository: UsersRepository) : ObservableViewModel() {
12 |
13 | val user = User("")
14 |
15 | @Bindable
16 | val bio = MutableLiveData()
17 |
18 | @Bindable
19 | val address = MutableLiveData()
20 |
21 | var isUpdatingUser = false
22 |
23 | val isUserReady: Boolean
24 | get() {
25 | user.run {
26 | return bio.isNotBlank()
27 | && address.isNotBlank()
28 | && bio != "null"
29 | && address != "null"
30 | }
31 | }
32 |
33 | val navigateUp: (View) -> Unit = {
34 | it.findNavController()
35 | .navigateUp()
36 | }
37 |
38 | fun get(user: User) = repository.get(user)
39 |
40 | fun update(view: View): UpdateUserViewModel {
41 | isUpdatingUser = true
42 | repository.update(user) {
43 | navigateUp(view)
44 | }
45 | return this
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/ui/users/update/UpdateUserViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.ui.users.update
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import io.github.horaciocome1.reaque.data.users.UsersRepository
6 |
7 | class UpdateUserViewModelFactory(private val repository: UsersRepository) :
8 | ViewModelProvider.NewInstanceFactory() {
9 |
10 | @Suppress("UNCHECKED_CAST")
11 | override fun create(modelClass: Class) =
12 | UpdateUserViewModel(repository) as T
13 |
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/Constants.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.util
17 |
18 | object Constants {
19 |
20 | const val DEFAULT = 123456789
21 |
22 | // StartActivityForResult
23 | const val PICK_IMAGE_FROM_GALLERY_REQUEST_CODE = 1207
24 | const val GOOGLE_SIGN_IN_REQUEST_CODE = 1208
25 | const val STORAGE_PERMISSION_CODE = 1209
26 |
27 | // Glide
28 | const val CIRCLE = 2307
29 | const val BLUR = 2308
30 |
31 | // list type
32 | const val LISTING_TOPICS = 4401
33 | const val LISTING_POSTS = 4403
34 | const val LISTING_USERS = 4405
35 |
36 | // hosts
37 | const val FEED_FRAGMENT = 5501
38 | const val EXPLORE_FRAGMENT = 5502
39 | const val POSTS_FRAGMENT = 5503
40 | const val CREATE_POST_FRAGMENT = 5504
41 | const val USERS_FRAGMENT = 5505
42 |
43 | // strings
44 | const val LANDING_PAGE = "https://reaque.firebaseapp.com"
45 | const val BOOKMARKS_REQUEST = "bookmarks"
46 | const val SUBSCRIPTIONS_REQUEST = "subscriptions"
47 | const val SUBSCRIBERS_REQUEST = "subscribers"
48 | const val TOPIC_POSTS_REQUEST = "topic_posts"
49 | const val TOPIC_USERS_REQUEST = "topic_users"
50 | const val USER_POSTS_REQUEST = "user_posts"
51 | const val USER_ID = "USER_ID"
52 | const val MAIN_ACTIVITY = "MainActivity"
53 |
54 | object SharedPreferences {
55 |
56 | const val NAME = "SharedPreferencesPostDraft"
57 | const val POST_TITLE = "SharedPreferencesPostDraftPostTitle"
58 | const val POST_MESSAGE = "SharedPreferencesPostDraftPostMessage"
59 |
60 | }
61 |
62 | // 3 states boolean
63 | object States {
64 | const val TRUE = 1
65 | const val FALSE = 0
66 | const val UNDEFINED = -1
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/DateUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque.util
17 |
18 | import com.google.firebase.Timestamp
19 | import java.util.*
20 |
21 | val Timestamp.string: String
22 | get() {
23 | val calendar = Calendar.getInstance()
24 | calendar.time = toDate()
25 | return calendar.month +
26 | " ${calendar[Calendar.DAY_OF_MONTH]}," +
27 | " ${calendar[Calendar.YEAR]}"
28 | }
29 |
30 | val Calendar.month: String
31 | get() = when (this[Calendar.MONTH]) {
32 | Calendar.JANUARY -> "Janeiro"
33 | Calendar.FEBRUARY -> "Fevereiro"
34 | Calendar.MARCH -> "Março"
35 | Calendar.APRIL -> "Abril"
36 | Calendar.MAY -> "Maio"
37 | Calendar.JUNE -> "Junho"
38 | Calendar.JULY -> "Julho"
39 | Calendar.AUGUST -> "Agosto"
40 | Calendar.SEPTEMBER -> "Setembro"
41 | Calendar.OCTOBER -> "Outubro"
42 | Calendar.NOVEMBER -> "Novembro"
43 | Calendar.DECEMBER -> "Dezembro"
44 | else -> "month"
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/DomainUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | package io.github.horaciocome1.reaque.util
18 |
19 | import com.google.firebase.auth.FirebaseUser
20 | import com.google.firebase.firestore.FieldValue
21 | import io.github.horaciocome1.reaque.data.posts.Post
22 | import io.github.horaciocome1.reaque.data.users.User
23 |
24 | val Post.map: Map
25 | get() = mapOf(
26 | "title" to title,
27 | "message" to message,
28 | "pic" to pic,
29 | "timestamp" to timestamp,
30 | "bookmarks" to 0,
31 | "readings" to 0,
32 | "rating" to 0,
33 | "shares" to 0,
34 | "score" to 0,
35 | "topic" to mapOf(
36 | "id" to topic.id,
37 | "title" to topic.title
38 | ),
39 | "user" to mapOf(
40 | "id" to user.id,
41 | "name" to user.name,
42 | "pic" to user.pic
43 | )
44 | )
45 |
46 | val Post.mapSimple: Map
47 | get() = mapOf(
48 | "id" to id,
49 | "title" to title,
50 | "pic" to pic,
51 | "timestamp" to timestamp,
52 | "topic" to mapOf(
53 | "id" to topic.id,
54 | "title" to topic.title
55 | ),
56 | "user" to mapOf(
57 | "id" to user.id,
58 | "name" to user.name,
59 | "pic" to user.pic
60 | ),
61 | "score" to score
62 | )
63 |
64 | val User.map: Map
65 | get() = mapOf(
66 | "id" to id,
67 | "name" to name,
68 | "pic" to pic,
69 | "subscribers" to subscribers,
70 | "top_topic" to topTopic,
71 | "score" to score,
72 | "timestamp" to FieldValue.serverTimestamp()
73 | )
74 |
75 | val User.mapSimple: Map
76 | get() = mapOf(
77 | "bio" to bio,
78 | "address" to address
79 | )
80 |
81 | val FirebaseUser.user: User
82 | get() = User(uid).apply {
83 | name = displayName.toString()
84 | pic = photoUrl.toString()
85 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/DynamicLinksUtils.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.util
2 |
3 | import android.content.Intent
4 | import android.net.Uri
5 | import com.google.android.gms.tasks.Task
6 | import com.google.firebase.dynamiclinks.DynamicLink
7 | import com.google.firebase.dynamiclinks.FirebaseDynamicLinks
8 | import com.google.firebase.dynamiclinks.ShortDynamicLink
9 | import io.github.horaciocome1.reaque.data.posts.Post
10 | import io.github.horaciocome1.reaque.ui.MainActivity
11 |
12 | fun FirebaseDynamicLinks.buildShortDynamicLink(
13 | post: Post,
14 | onSuccessListener: (Intent) -> Unit
15 | ): Task {
16 | return createDynamicLink()
17 | .setLink(Uri.parse("${Constants.LANDING_PAGE}/${post.id}"))
18 | .setDomainUriPrefix("https://reaque.page.link")
19 | .setAndroidParameters(
20 | DynamicLink.AndroidParameters.Builder()
21 | .setFallbackUrl(Uri.parse(Constants.LANDING_PAGE))
22 | .build()
23 | )
24 | .setIosParameters(
25 | DynamicLink.IosParameters.Builder("")
26 | .setFallbackUrl(Uri.parse(Constants.LANDING_PAGE))
27 | .setIpadFallbackUrl(Uri.parse(Constants.LANDING_PAGE))
28 | .build()
29 | )
30 | .setSocialMetaTagParameters(
31 | DynamicLink.SocialMetaTagParameters.Builder()
32 | .setTitle("${post.title} - ${post.user.name}")
33 | .setDescription(post.message)
34 | .setImageUrl(Uri.parse(post.pic))
35 | .build()
36 | )
37 | .buildShortDynamicLink()
38 | .addOnSuccessListener {
39 | val sendIntent = Intent().apply {
40 | action = Intent.ACTION_SEND
41 | putExtra(Intent.EXTRA_TEXT, it.shortLink.toString())
42 | type = "text/plain"
43 | }
44 | val chooser = Intent.createChooser(sendIntent, post.title)
45 | onSuccessListener(chooser)
46 | }
47 | }
48 |
49 | fun MainActivity.handleDynamicLinks(onSuccessListener: (Post) -> Unit) {
50 | FirebaseDynamicLinks.getInstance()
51 | .getDynamicLink(intent)
52 | .addOnSuccessListener {
53 | it?.let {
54 | val postId: String = it.link
55 | .toString()
56 | .removePrefix("${Constants.LANDING_PAGE}/")
57 | val post = Post(postId)
58 | onSuccessListener(post)
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/ObservableViewModel.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.util
2 |
3 | import androidx.databinding.Observable
4 | import androidx.databinding.PropertyChangeRegistry
5 | import androidx.lifecycle.ViewModel
6 |
7 | open class ObservableViewModel: ViewModel(), Observable {
8 |
9 | private val callbacks: PropertyChangeRegistry by lazy {
10 | PropertyChangeRegistry()
11 | }
12 |
13 | override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
14 | callbacks.remove(callback)
15 | }
16 |
17 | override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
18 | callbacks.add(callback)
19 | }
20 |
21 | // notifies listeners that all properties of this instance have changed
22 | @Suppress("unused")
23 | fun notifyChange() = callbacks.notifyCallbacks(this, 0, null)
24 |
25 | // notifies listeners that a specific property has changed.
26 | // the getter for the property that changes should be marked with [@Bindable]
27 | // to generate a field in `BR` to be used as `fieldId`
28 | fun notifyPropertyChanged(fieldId: Int) = callbacks.notifyCallbacks(this, fieldId, null)
29 |
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/OnFocusChangeListener.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.util
2 |
3 | import android.content.Context
4 | import android.view.View
5 | import android.view.inputmethod.InputMethodManager
6 | import com.google.android.material.textfield.TextInputEditText
7 |
8 | class OnFocusChangeListener(private val context: Context?) : View.OnFocusChangeListener {
9 |
10 | override fun onFocusChange(view: View?, hasFocus: Boolean) {
11 | if (view is TextInputEditText && !hasFocus) {
12 | val service = context?.getSystemService(Context.INPUT_METHOD_SERVICE)
13 | if (service is InputMethodManager)
14 | service.hideSoftInputFromWindow(view.windowToken, 0)
15 | }
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/horaciocome1/reaque/util/QuerySnapshotUtils.kt:
--------------------------------------------------------------------------------
1 | package io.github.horaciocome1.reaque.util
2 |
3 | import com.google.firebase.firestore.QuerySnapshot
4 | import io.github.horaciocome1.reaque.data.posts.Post
5 | import io.github.horaciocome1.reaque.data.topics.Topic
6 | import io.github.horaciocome1.reaque.data.users.User
7 |
8 | val QuerySnapshot.topics: MutableList
9 | get() {
10 | val list = mutableListOf()
11 | forEach {
12 | list.add(it.topic)
13 | }
14 | return list
15 | }
16 |
17 | val QuerySnapshot.users: MutableList
18 | get() {
19 | val list = mutableListOf()
20 | forEach {
21 | list.add(it.user)
22 | }
23 | return list
24 | }
25 |
26 | val QuerySnapshot.posts: MutableList
27 | get() {
28 | val list = mutableListOf()
29 | forEach {
30 | list.add(it.post)
31 | }
32 | return list
33 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
27 |
28 |
34 |
37 |
40 |
41 |
42 |
43 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_all_corners_rounded_secondary.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_bottomsheet.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_bottomsheet_stroke.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_shadow_bottom_to_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_bookmark_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/color_bottom_navigation.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/color_side_navigation.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_access_time_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_add_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_add_photo_alternate_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_arrow_forward_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_bookmark_border_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_bookmarks_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_close_24.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_cloud_download_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_drag_handle_24.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_edit_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_exit_to_app_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_explore_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_feedback_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_info_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_info_24.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_library_books_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_location_on_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_more_horiz_24.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_people_outline_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_share_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_short_text_18.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_subject_18.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_whatshot_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/font/roboto.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/font/roboto_light.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/font/roboto_medium.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/font/roboto_thin.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/activity_main.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
24 |
25 |
28 |
29 |
35 |
36 |
44 |
45 |
46 |
47 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-v21/fragment_explore.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
18 |
19 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-v21/fragment_user_profile.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
20 |
21 |
29 |
30 |
35 |
36 |
44 |
45 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w600dp/layout_explore_topics_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w600dp/layout_feed_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w600dp/layout_posts_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w600dp/layout_users_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w900dp/layout_explore_topics_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w900dp/layout_feed_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w900dp/layout_posts_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-w900dp/layout_users_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_create_post.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
18 |
19 |
22 |
23 |
28 |
29 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
46 |
47 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
64 |
65 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_explore.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
17 |
18 |
22 |
23 |
26 |
27 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
20 |
21 |
25 |
26 |
32 |
33 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_more.xml:
--------------------------------------------------------------------------------
1 |
15 |
17 |
18 |
19 |
20 |
23 |
24 |
27 |
28 |
29 |
30 |
35 |
36 |
40 |
41 |
47 |
48 |
52 |
53 |
54 |
55 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_posts.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
19 |
20 |
24 |
25 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_set_rating.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
29 |
30 |
47 |
48 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_update_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
15 |
16 |
17 |
18 |
24 |
25 |
33 |
34 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_user_profile.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
14 |
15 |
16 |
17 |
21 |
22 |
26 |
27 |
32 |
33 |
40 |
41 |
46 |
47 |
54 |
55 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_users.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
19 |
20 |
24 |
25 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_suggestion.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
19 |
20 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_topic.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
19 |
25 |
26 |
33 |
34 |
35 |
36 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_appbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_create_post_loading_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
19 |
20 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_explore_suggestions_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_explore_topics_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_feed_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_more_footer_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
24 |
25 |
29 |
30 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_more_session_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
16 |
17 |
37 |
38 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_posts_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_update_user_loading_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
19 |
20 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_users_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 | #ffffff
19 | #ffffff
20 | #7c4dff
21 | #b47cff
22 | #3f1dcb
23 | #ffffff
24 | #f44336
25 |
26 |
27 | #ff6d00
28 | #00c853
29 | #99000000
30 |
31 | #10000000
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 1dp
6 | 2dp
7 | 16dp
8 | 16dp
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 | #fafafa
19 | #ffffff
20 | #7c4dff
21 | #b47cff
22 | #3f1dcb
23 | #000000
24 | #ffffff
25 | #F44336
26 |
27 |
28 | #ff6d00
29 | #00c853
30 | #99000000
31 |
32 | #50000000
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 | 0dp
19 | 1dp
20 | 2dp
21 | 16dp
22 | 16dp
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FAFAFA
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/preloaded_fonts.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 | - @font/roboto
20 | - @font/roboto_light
21 | - @font/roboto_medium
22 | - @font/roboto_thin
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_descriptor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/test/java/io/github/horaciocome1/reaque/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | package io.github.horaciocome1.reaque
17 |
18 | import org.junit.Assert.assertEquals
19 | import org.junit.Test
20 |
21 | /**
22 | * Example local unit test, which will execute on the development machine (host).
23 | *
24 | * See [testing documentation](http://d.android.com/tools/testing).
25 | */
26 | class ExampleUnitTest {
27 | @Test
28 | fun addition_isCorrect() {
29 | assertEquals(4, 2 + 2)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
17 |
18 | buildscript {
19 | ext.kotlin_version = '1.3.50'
20 | ext.nav_version = '1.0.0'
21 | repositories {
22 | google()
23 | jcenter()
24 | maven {
25 | url 'https://maven.fabric.io/public'
26 | }
27 | }
28 | dependencies {
29 | classpath 'com.android.tools.build:gradle:3.5.0'
30 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
31 | classpath 'com.google.gms:google-services:4.3.1'
32 | classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:$nav_version"
33 | classpath 'com.google.firebase:perf-plugin:1.3.1'
34 | classpath 'io.fabric.tools:gradle:1.28.0'
35 |
36 | // NOTE: Do not place your application dependencies here; they belong
37 | // in the individual module build.gradle files
38 | }
39 | }
40 |
41 | allprojects {
42 | repositories {
43 | google()
44 | jcenter()
45 | maven {
46 | url 'https://jitpack.io'
47 | }
48 | }
49 | }
50 |
51 | task clean(type: Delete) {
52 | delete rootProject.buildDir
53 | }
--------------------------------------------------------------------------------
/docs/DONATE.md:
--------------------------------------------------------------------------------
1 | # Donate
2 | Welcome, and it is my pleasure to see you here.
3 | If you want to help me as a developer, [please read this](https://github.com/horaciocome1/reaque/tree/polishing-foreground-and-background#for-developers-only-2)
4 |
5 | ## Financial support
6 | This is am open source project and is mainly maintained by donations. There are several channels in which you may achieve this.
7 |
8 | ### Mpesa
9 | You can donate using [Vodacom Mpesa](https://www.vm.co.mz/en/M-Pesa2) by sending your donation to _**84 384 5597**_.
10 |
11 | Thank you!
--------------------------------------------------------------------------------
/docs/diagrams/reaque-architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/docs/diagrams/reaque-architecture.jpg
--------------------------------------------------------------------------------
/docs/diagrams/use_case.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/docs/diagrams/use_case.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2019 Hor�cio Fl�vio Com� J�nior
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and limitations under the License.
14 | #
15 | org.gradle.jvmargs=-Xmx1536m
16 |
17 | # SPEED UP GRADLE
18 | #org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
19 |
20 | # When configured, Gradle will run in incubating parallel mode.
21 | # This option should only be used with decoupled projects. More details, visit
22 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
23 |
24 | # SPEED UP GRADLE
25 | #org.gradle.parallel=true
26 |
27 | # Kotlin code style for this project: "official" or "obsolete":
28 | kotlin.code.style=official
29 |
30 | # androidx
31 | android.useAndroidX=true
32 | android.enableJetifier=true
33 |
34 | # code shrinker
35 | android.enableR8=true
36 |
37 | # databinding
38 | android.databinding.incremental=true
39 |
40 | # Enable the incremental annotation processing experimental flag SPEED UP GRADLE
41 | kapt.incremental.apt=true
42 | # SPEED UP GRADLE
43 | #org.gradle.configureondemand=true
44 | #-Pandroid.debug.obsoleteApi=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Aug 27 15:11:09 CAT 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.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/screenshots/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/logo.png
--------------------------------------------------------------------------------
/screenshots/mock1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/mock1.png
--------------------------------------------------------------------------------
/screenshots/mock2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/mock2.png
--------------------------------------------------------------------------------
/screenshots/mock3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/mock3.png
--------------------------------------------------------------------------------
/screenshots/screen1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen1.png
--------------------------------------------------------------------------------
/screenshots/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen2.png
--------------------------------------------------------------------------------
/screenshots/screen3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen3.png
--------------------------------------------------------------------------------
/screenshots/screen4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen4.png
--------------------------------------------------------------------------------
/screenshots/screen5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen5.png
--------------------------------------------------------------------------------
/screenshots/screen6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen6.png
--------------------------------------------------------------------------------
/screenshots/screen7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen7.png
--------------------------------------------------------------------------------
/screenshots/screen8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/horaciocome1/reaque-android-app/6a2409e318805da4f89ddd5cebf9c0687c356e5f/screenshots/screen8.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Horácio Flávio Comé Júnior
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and limitations under the License.
14 | */
15 |
16 | include ':app'
17 |
--------------------------------------------------------------------------------