├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── raw
│ │ │ │ └── map_style.json
│ │ │ ├── drawable
│ │ │ │ ├── profile.png
│ │ │ │ ├── bg_gradient.xml
│ │ │ │ ├── rounded_dialog.xml
│ │ │ │ ├── image_rounded.xml
│ │ │ │ ├── ic_message.xml
│ │ │ │ ├── rounded_indicator.xml
│ │ │ │ ├── ic_un_saved.xml
│ │ │ │ ├── ic_play.xml
│ │ │ │ ├── ic_pdf.xml
│ │ │ │ ├── ic_theme.xml
│ │ │ │ ├── ic_offline.xml
│ │ │ │ ├── bg_decorator.xml
│ │ │ │ ├── ic_menu_dots.xml
│ │ │ │ ├── ic_menu_rate.xml
│ │ │ │ ├── ic_menu_saved.xml
│ │ │ │ ├── ic_menu_love_color.xml
│ │ │ │ ├── ic_menu_love.xml
│ │ │ │ ├── ic_menu_favorite_animation.xml
│ │ │ │ ├── ic_linkedin.xml
│ │ │ │ ├── ic_menu_profile_animation.xml
│ │ │ │ ├── ic_menu_settings_animation.xml
│ │ │ │ ├── ic_menu_portfolio_animation.xml
│ │ │ │ ├── ic_saved.xml
│ │ │ │ ├── ic_menu_experience_animation.xml
│ │ │ │ ├── ic_youtube.xml
│ │ │ │ ├── ic_menu_portfolio.xml
│ │ │ │ ├── ic_play_store.xml
│ │ │ │ ├── ic_duration.xml
│ │ │ │ ├── ic_menu_top_favorite.xml
│ │ │ │ ├── ic_menu_save.xml
│ │ │ │ ├── ic_close.xml
│ │ │ │ ├── ic_twitter.xml
│ │ │ │ ├── ic_menu_search.xml
│ │ │ │ ├── ic_map.xml
│ │ │ │ ├── ic_rate.xml
│ │ │ │ ├── ic_menu_profile.xml
│ │ │ │ ├── ic_github.xml
│ │ │ │ ├── ic_link.xml
│ │ │ │ ├── ic_empty.xml
│ │ │ │ ├── ic_fab_profile.xml
│ │ │ │ ├── ic_privacy.xml
│ │ │ │ ├── ic_menu_privacy.xml
│ │ │ │ ├── ic_read_more.xml
│ │ │ │ ├── ic_wifi.xml
│ │ │ │ ├── ic_menu_experience.xml
│ │ │ │ ├── ic_avatar_placeholder.xml
│ │ │ │ ├── ic_profile_placeholder.xml
│ │ │ │ ├── ic_menu_refresh.xml
│ │ │ │ ├── ic_launcher_foreground.xml
│ │ │ │ ├── ic_globe.xml
│ │ │ │ ├── ic_email.xml
│ │ │ │ ├── ic_logo.xml
│ │ │ │ ├── ic_menu_settings.xml
│ │ │ │ ├── ic_category_code.xml
│ │ │ │ ├── ic_no_connection.xml
│ │ │ │ ├── ic_hand_waving.xml
│ │ │ │ ├── ic_menu_share.xml
│ │ │ │ ├── ic_category_structure.xml
│ │ │ │ ├── ic_app_info_update.xml
│ │ │ │ └── ic_category_web.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── values
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ ├── preloaded_fonts.xml
│ │ │ │ ├── arrays.xml
│ │ │ │ ├── attrs.xml
│ │ │ │ └── dimens.xml
│ │ │ ├── anim
│ │ │ │ ├── slide_up.xml
│ │ │ │ ├── slide_down.xml
│ │ │ │ ├── fade_in.xml
│ │ │ │ └── fade_out.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── color
│ │ │ │ ├── side_navigation_icon_color.xml
│ │ │ │ ├── side_navigation_text_color.xml
│ │ │ │ ├── button_full_color.xml
│ │ │ │ └── button_outline_icon_text_border_color.xml
│ │ │ ├── font
│ │ │ │ ├── questrial.xml
│ │ │ │ └── roboto_thin.xml
│ │ │ ├── layout
│ │ │ │ ├── header_placeholder.xml
│ │ │ │ ├── fragment_welcome.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── screen_profile_about.xml
│ │ │ │ ├── fragment_experience.xml
│ │ │ │ ├── preference_category_title.xml
│ │ │ │ ├── preference_category_footer.xml
│ │ │ │ ├── fragment_portfolio.xml
│ │ │ │ ├── list_item_about.xml
│ │ │ │ ├── list_item_screenshot.xml
│ │ │ │ ├── list_item_about_header.xml
│ │ │ │ └── preference_item_icon_title.xml
│ │ │ ├── menu
│ │ │ │ ├── favorite_list_menu.xml
│ │ │ │ ├── portfolio_list_menu.xml
│ │ │ │ ├── bottom_menu.xml
│ │ │ │ ├── profile_menu.xml
│ │ │ │ ├── side_menu.xml
│ │ │ │ └── portfolio_detail_menu.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── assets
│ │ │ └── koin.properties
│ │ ├── ic_launcher-web.png
│ │ ├── java
│ │ │ └── me
│ │ │ │ └── tumur
│ │ │ │ └── portfolio
│ │ │ │ ├── utils
│ │ │ │ ├── state
│ │ │ │ │ ├── FavoriteState.kt
│ │ │ │ │ ├── PreviewState.kt
│ │ │ │ │ ├── ToastState.kt
│ │ │ │ │ ├── NavigationState.kt
│ │ │ │ │ └── ScreenState.kt
│ │ │ │ ├── adapters
│ │ │ │ │ └── listItemAdapters
│ │ │ │ │ │ ├── portfolio
│ │ │ │ │ │ ├── button
│ │ │ │ │ │ │ ├── ButtonClickListener.kt
│ │ │ │ │ │ │ ├── ButtonItem.kt
│ │ │ │ │ │ │ ├── ButtonDiffCallBack.kt
│ │ │ │ │ │ │ ├── ButtonNormalViewHolder.kt
│ │ │ │ │ │ │ └── ButtonOutlineViewHolder.kt
│ │ │ │ │ │ ├── PortfolioClickListener.kt
│ │ │ │ │ │ ├── screenshot
│ │ │ │ │ │ │ ├── ScreenShotClickListener.kt
│ │ │ │ │ │ │ ├── ScreenShotDiffCallBack.kt
│ │ │ │ │ │ │ ├── ScreenShotViewHolder.kt
│ │ │ │ │ │ │ └── ScreenShotAdapter.kt
│ │ │ │ │ │ ├── PortfolioDiffCallBack.kt
│ │ │ │ │ │ ├── category
│ │ │ │ │ │ │ ├── CategoryDiffCallBack.kt
│ │ │ │ │ │ │ ├── CategoryViewHolder.kt
│ │ │ │ │ │ │ └── CategoryAdapter.kt
│ │ │ │ │ │ ├── PortfolioViewHolder.kt
│ │ │ │ │ │ └── PortfolioAdapter.kt
│ │ │ │ │ │ ├── social
│ │ │ │ │ │ ├── SocialClickListener.kt
│ │ │ │ │ │ ├── SocialDiffCallBack.kt
│ │ │ │ │ │ ├── SocialViewHolder.kt
│ │ │ │ │ │ └── SocialAdapter.kt
│ │ │ │ │ │ ├── experience
│ │ │ │ │ │ ├── ExperienceClickListener.kt
│ │ │ │ │ │ ├── task
│ │ │ │ │ │ │ ├── TaskDiffCallBack.kt
│ │ │ │ │ │ │ ├── TaskViewHolder.kt
│ │ │ │ │ │ │ └── TaskAdapter.kt
│ │ │ │ │ │ ├── ExperienceDiffCallBack.kt
│ │ │ │ │ │ ├── resource
│ │ │ │ │ │ │ ├── ResourceDiffCallBack.kt
│ │ │ │ │ │ │ ├── ResourceViewHolder.kt
│ │ │ │ │ │ │ └── ResourceAdapter.kt
│ │ │ │ │ │ ├── ExperienceViewHolder.kt
│ │ │ │ │ │ └── ExperienceAdapter.kt
│ │ │ │ │ │ ├── favorite
│ │ │ │ │ │ ├── FavoriteClickListener.kt
│ │ │ │ │ │ ├── FavoriteDiffCallBack.kt
│ │ │ │ │ │ ├── FavoriteViewHolder.kt
│ │ │ │ │ │ └── FavoriteAdapter.kt
│ │ │ │ │ │ ├── about
│ │ │ │ │ │ ├── AboutItem.kt
│ │ │ │ │ │ ├── AboutDiffCallBack.kt
│ │ │ │ │ │ ├── AboutItemViewHolder.kt
│ │ │ │ │ │ └── AboutHeaderViewHolder.kt
│ │ │ │ │ │ └── app
│ │ │ │ │ │ ├── AppDiffCallBack.kt
│ │ │ │ │ │ ├── AppViewHolder.kt
│ │ │ │ │ │ └── AppAdapter.kt
│ │ │ │ ├── extensions
│ │ │ │ │ ├── Databinding.kt
│ │ │ │ │ ├── ViewGroupExtensions.kt
│ │ │ │ │ └── isNetworkAvailable.kt
│ │ │ │ ├── constants
│ │ │ │ │ └── BsConstants.kt
│ │ │ │ ├── delegates
│ │ │ │ │ └── Databinding.kt
│ │ │ │ ├── toolbar
│ │ │ │ │ └── CollapsibleToolbar.kt
│ │ │ │ ├── theme
│ │ │ │ │ └── ThemeHelper.kt
│ │ │ │ └── fabButton
│ │ │ │ │ └── ScrollAwareFabButton.kt
│ │ │ │ ├── screens
│ │ │ │ ├── portfolio
│ │ │ │ │ └── detail
│ │ │ │ │ │ ├── VideoClickListener.kt
│ │ │ │ │ │ └── preview
│ │ │ │ │ │ └── pager
│ │ │ │ │ │ ├── PreviewPagerAdapter.kt
│ │ │ │ │ │ └── PreviewPagerViewModel.kt
│ │ │ │ ├── welcome
│ │ │ │ │ └── pager
│ │ │ │ │ │ ├── WelcomePagerAdapter.kt
│ │ │ │ │ │ └── WelcomePagerViewModel.kt
│ │ │ │ ├── settings
│ │ │ │ │ └── dialog
│ │ │ │ │ │ └── AppDialogViewModel.kt
│ │ │ │ └── experience
│ │ │ │ │ └── ExperienceViewModel.kt
│ │ │ │ └── repository
│ │ │ │ ├── network
│ │ │ │ ├── Result.kt
│ │ │ │ └── RestApi.kt
│ │ │ │ ├── database
│ │ │ │ ├── Converters.kt
│ │ │ │ ├── dao
│ │ │ │ │ ├── settings
│ │ │ │ │ │ └── AppDao.kt
│ │ │ │ │ ├── profile
│ │ │ │ │ │ ├── AboutDao.kt
│ │ │ │ │ │ ├── SocialDao.kt
│ │ │ │ │ │ └── ProfileDao.kt
│ │ │ │ │ ├── task
│ │ │ │ │ │ └── TaskDao.kt
│ │ │ │ │ ├── button
│ │ │ │ │ │ └── ButtonDao.kt
│ │ │ │ │ ├── location
│ │ │ │ │ │ └── LocationDao.kt
│ │ │ │ │ ├── category
│ │ │ │ │ │ └── CategoryDao.kt
│ │ │ │ │ ├── resource
│ │ │ │ │ │ └── ResourceDao.kt
│ │ │ │ │ ├── experience
│ │ │ │ │ │ └── ExperienceDao.kt
│ │ │ │ │ ├── screenshot
│ │ │ │ │ │ └── ScreenShotDao.kt
│ │ │ │ │ ├── welcome
│ │ │ │ │ │ └── WelcomeDao.kt
│ │ │ │ │ ├── portfolio
│ │ │ │ │ │ └── PortfolioDao.kt
│ │ │ │ │ └── favorite
│ │ │ │ │ │ └── FavoriteDao.kt
│ │ │ │ └── model
│ │ │ │ │ ├── settings
│ │ │ │ │ └── AppModel.kt
│ │ │ │ │ ├── task
│ │ │ │ │ └── TaskModel.kt
│ │ │ │ │ ├── profile
│ │ │ │ │ ├── AboutModel.kt
│ │ │ │ │ ├── SocialModel.kt
│ │ │ │ │ └── ProfileModel.kt
│ │ │ │ │ ├── LocationModel.kt
│ │ │ │ │ ├── welcome
│ │ │ │ │ └── WelcomeModel.kt
│ │ │ │ │ ├── screenshot
│ │ │ │ │ └── ScreenShotModel.kt
│ │ │ │ │ ├── button
│ │ │ │ │ └── ButtonModel.kt
│ │ │ │ │ ├── category
│ │ │ │ │ └── CategoryModel.kt
│ │ │ │ │ ├── resource
│ │ │ │ │ └── ResourceModel.kt
│ │ │ │ │ ├── favorite
│ │ │ │ │ └── FavoriteModel.kt
│ │ │ │ │ └── experience
│ │ │ │ │ └── ExperienceModel.kt
│ │ │ │ └── repo
│ │ │ │ └── Repository.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── me
│ │ │ └── tumur
│ │ │ └── portfolio
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── me
│ │ └── tumur
│ │ └── portfolio
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── google-services.json
├── .idea
├── .gitignore
├── codeStyles
│ └── codeStyleConfig.xml
├── encodings.xml
├── vcs.xml
├── kotlinc.xml
├── render.experimental.xml
├── dictionaries
│ └── Tumur.xml
├── runConfigurations.xml
├── gradle.xml
└── misc.xml
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── utils.gradle
└── gradle.properties
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/src/main/res/raw/map_style.json:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name='Portfolio'
3 |
--------------------------------------------------------------------------------
/app/src/main/assets/koin.properties:
--------------------------------------------------------------------------------
1 | URL=https://portfolio-app-147b5.web.app/
2 | CONNECT=30
3 | READ=60
4 | WRITE=60
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable/profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/drawable/profile.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timtbdev/Android-Portfolio-App-2/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #9AA0A6
4 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/render.experimental.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/preloaded_fonts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @font/questrial
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/state/FavoriteState.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.state
2 |
3 | sealed class FavoriteState
4 |
5 | /** Empty */
6 | object Empty : FavoriteState()
7 |
8 | /** Not Empty */
9 | object NotEmpty : FavoriteState()
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/portfolio/detail/VideoClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.portfolio.detail
2 |
3 | class VideoClickListener(val clickListener: (url: String) -> Unit) {
4 | fun onClick(url: String) = clickListener(url)
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/network/Result.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.network
2 |
3 | sealed class Result
4 |
5 | /** Network request successful */
6 | object Success : Result()
7 |
8 | /** Network request failed */
9 | object Failed : Result()
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/state/PreviewState.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.state
2 |
3 | sealed class PreviewState
4 |
5 | /** Show progress bar */
6 | object ProgressBar : PreviewState()
7 |
8 | /** Hide progress bar */
9 | object PreviewImage : PreviewState()
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Sep 26 22:36:14 PDT 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.6.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/button/ButtonClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button
2 |
3 | class ButtonClickListener(val clickListener: (url: String) -> Unit) {
4 | fun onClick(url: String) = clickListener(url)
5 | }
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_gradient.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/network/RestApi.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.network
2 |
3 | import me.tumur.portfolio.repository.database.model.all.RequestAll
4 | import retrofit2.Response
5 | import retrofit2.http.GET
6 |
7 | interface RestApi {
8 |
9 | @GET("api/all/")
10 | suspend fun getAll(): Response
11 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/state/ToastState.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.state
2 |
3 | sealed class ToastState
4 |
5 | /** Saved */
6 | object ToastSaved : ToastState()
7 |
8 | /** Unsaved */
9 | object ToastUnsaved : ToastState()
10 |
11 | /** Show */
12 | object ToastShow : ToastState()
13 |
14 | /** Showed */
15 | object ToastEmpty : ToastState()
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/state/NavigationState.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.state
2 |
3 | sealed class NavigationState
4 |
5 | /** Hide Navigation */
6 | object HideNavigation: NavigationState()
7 |
8 | /** Show Navigation */
9 | object ShowNavigation : NavigationState()
10 |
11 | /** Hide Bottom navigation */
12 | object GoneNavigation : NavigationState()
--------------------------------------------------------------------------------
/app/src/main/res/color/side_navigation_icon_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/social/SocialClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.social
2 |
3 | import me.tumur.portfolio.repository.database.model.profile.SocialModel
4 |
5 | class SocialClickListener(val clickListener: (socialItem: SocialModel) -> Unit){
6 | fun onClick(item: SocialModel) = clickListener(item)
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/extensions/Databinding.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.extensions
2 |
3 | import androidx.annotation.LayoutRes
4 | import androidx.databinding.ViewDataBinding
5 | import me.tumur.portfolio.utils.delegates.ActivityBindingProperty
6 |
7 | internal fun activityBinding(@LayoutRes resId: Int) =
8 | ActivityBindingProperty(resId)
--------------------------------------------------------------------------------
/app/src/main/res/color/side_navigation_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/PortfolioClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio
2 |
3 | import me.tumur.portfolio.repository.database.model.portfolio.PortfolioModel
4 |
5 | class PortfolioClickListener(val clickListener: (item: PortfolioModel) -> Unit) {
6 | fun onClick(item: PortfolioModel) = clickListener(item)
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/ExperienceClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience
2 |
3 | import me.tumur.portfolio.repository.database.model.experience.ExperienceModel
4 |
5 | class ExperienceClickListener(val clickListener: (item: ExperienceModel) -> Unit) {
6 | fun onClick(item: ExperienceModel) = clickListener(item)
7 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/image_rounded.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/state/ScreenState.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.state
2 |
3 | sealed class ScreenState
4 |
5 | /** Splash Screen */
6 | object SplashScreen: ScreenState()
7 |
8 | /** Welcome Screen */
9 | object WelcomeScreen : ScreenState()
10 |
11 | /** Main Screen */
12 | object MainScreen : ScreenState()
13 |
14 | /** Loader Screen */
15 | object LoaderScreen : ScreenState()
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/font/questrial.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/header_placeholder.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/favorite/FavoriteClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.favorite
2 |
3 | import me.tumur.portfolio.repository.database.model.favorite.FavoriteModel
4 |
5 | class FavoriteClickListener(val clickListener: (item: FavoriteModel, delete: Boolean) -> Unit) {
6 | fun onClick(item: FavoriteModel, delete: Boolean) = clickListener(item, delete)
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/screenshot/ScreenShotClickListener.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.screenshot
2 |
3 | import me.tumur.portfolio.repository.database.model.screenshot.ScreenShotModel
4 |
5 | class ScreenShotClickListener(val clickListener: (model: ScreenShotModel) -> Unit) {
6 | fun onClick(model: ScreenShotModel) = clickListener(model)
7 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - Light
5 | - Dark
6 | - Default
7 |
8 |
9 |
10 | - light
11 | - dark
12 | - default
13 |
14 |
--------------------------------------------------------------------------------
/.idea/dictionaries/Tumur.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | appinfo
5 | bottomsheet
6 | coroutine
7 | databinding
8 | drawerlayout
9 | linkedin
10 | recyclerview
11 | sucessfull
12 | tumur
13 | viewholder
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/extensions/ViewGroupExtensions.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.extensions
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.annotation.LayoutRes
7 |
8 | fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View {
9 | return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot)
10 | }
--------------------------------------------------------------------------------
/app/src/main/res/font/roboto_thin.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_message.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/Converters.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database
2 |
3 | import androidx.room.TypeConverter
4 | import java.util.*
5 |
6 | class Converters {
7 | @TypeConverter
8 | fun fromTimestamp(value: Long?): Date? {
9 | return value?.let { Date(it) }
10 | }
11 |
12 | @TypeConverter
13 | fun dateToTimestamp(date: Date?): Long? {
14 | return date?.time
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/repo/Repository.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.repo
2 |
3 | import me.tumur.portfolio.repository.network.Result
4 |
5 | interface Repository {
6 |
7 | /** MAIN SCREEN ------------------------------------------------------------------------------------------------- */
8 |
9 | /**
10 | * Fetch data from network and update the database
11 | */
12 | suspend fun fetchAll(): Result
13 | }
--------------------------------------------------------------------------------
/app/src/test/java/me/tumur/portfolio/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ...
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | ...
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_indicator.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_un_saved.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_play.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/constants/BsConstants.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.constants
2 |
3 | object BsConstants {
4 |
5 | /** * * * * * * * * * * * * * BOTTOM SHEET * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6 |
7 | /** Profile bottom sheet constants ----------------------------------------------------------------------------- */
8 | const val GITHUB = "Github"
9 | const val LINKEDIN = "LinkedIn"
10 | const val TWITTER = "Twitter"
11 | const val PDF = "Resume"
12 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_pdf.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/color/button_full_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_theme.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_offline.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_decorator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 | -
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_dots.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_rate.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_saved.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_love_color.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_love.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/utils.gradle:
--------------------------------------------------------------------------------
1 | ext.getVersionCode = {
2 | majorVersion, minorVersion, patchVersion, buildVersion ->
3 | return majorVersion * 10000000 + minorVersion * 100000 + patchVersion * 1000 + buildVersion
4 | }
5 |
6 | ext.getVersionName = {
7 | majorVersion, minorVersion, patchVersion ->
8 | return "${majorVersion}.${minorVersion}.${patchVersion}"
9 | }
10 |
11 | ext.renameArtifact = {
12 | name, variant ->
13 | variant.outputs.all {
14 | output ->
15 | def date = new Date().format("yyyyMMdd")
16 | outputFileName = "${name}-${project.name}-${variant.versionName}-${variant.versionCode}-${date}-${variant.name}.apk"
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_favorite_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_linkedin.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_profile_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_settings_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_portfolio_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_saved.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/about/AboutItem.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.about
2 |
3 | import androidx.recyclerview.widget.RecyclerView
4 | import me.tumur.portfolio.repository.database.model.profile.AboutModel
5 |
6 | /**
7 | * Sealed class for composited list data
8 | * to differentiate [AboutItemViewHolder] and [AboutHeaderViewHolder]
9 | * for [RecyclerView]
10 | * */
11 | sealed class AboutItem {
12 | data class About(val about: AboutModel): AboutItem() {
13 | override val id = about.id
14 | }
15 |
16 | data class Header(val header: String): AboutItem() {
17 | override val id = header
18 | }
19 |
20 | abstract val id: String
21 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_experience_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_youtube.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_portfolio.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_play_store.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_duration.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_top_favorite.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_save.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/button/ButtonItem.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button
2 |
3 | import androidx.recyclerview.widget.RecyclerView
4 | import me.tumur.portfolio.repository.database.model.button.ButtonModel
5 |
6 | /**
7 | * Sealed class for composited list data
8 | * to differentiate [ButtonOutlineViewHolder] and [ButtonNormalViewHolder]
9 | * for [RecyclerView]
10 | * */
11 | sealed class ButtonItem {
12 | data class ButtonOutline(val outline: ButtonModel) : ButtonItem() {
13 | override val id = outline.id
14 | }
15 |
16 | data class ButtonNormal(val normal: ButtonModel) : ButtonItem() {
17 | override val id = normal.id
18 | }
19 |
20 | abstract val id: String
21 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_close.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/me/tumur/portfolio/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("me.tumur.portfolio", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_twitter.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/welcome/pager/WelcomePagerAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.welcome.pager
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.Fragment
5 | import androidx.fragment.app.FragmentManager
6 | import androidx.fragment.app.FragmentStatePagerAdapter
7 | import me.tumur.portfolio.utils.constants.Constants.POSITION
8 |
9 | class WelcomePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
10 |
11 | override fun getCount(): Int = 3
12 |
13 | override fun getItem(i: Int): Fragment {
14 | val fragment = WelcomePagerFragment()
15 | fragment.arguments = Bundle().apply {
16 | // Our object is just an integer :-P
17 | putInt(POSITION, i)
18 | }
19 | return fragment
20 | }
21 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/res/color/button_outline_icon_text_border_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/favorite_list_menu.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/portfolio_list_menu.xml:
--------------------------------------------------------------------------------
1 |
3 | -
10 |
11 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/portfolio/detail/preview/pager/PreviewPagerAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.portfolio.detail.preview.pager
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.Fragment
5 | import androidx.fragment.app.FragmentManager
6 | import androidx.fragment.app.FragmentStatePagerAdapter
7 | import me.tumur.portfolio.utils.constants.Constants
8 |
9 | class PreviewPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
10 |
11 | override fun getCount(): Int = 6
12 |
13 | override fun getItem(i: Int): Fragment {
14 | val fragment = PreviewPagerFragment()
15 | fragment.arguments = Bundle().apply {
16 | // Our object is just an integer :-P
17 | putInt(Constants.POSITION, i)
18 | }
19 | return fragment
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_search.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/delegates/Databinding.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.delegates
2 |
3 | import android.app.Activity
4 | import androidx.annotation.LayoutRes
5 | import androidx.databinding.DataBindingUtil
6 | import androidx.databinding.ViewDataBinding
7 | import kotlin.properties.ReadOnlyProperty
8 | import kotlin.reflect.KProperty
9 |
10 | internal class ActivityBindingProperty(@LayoutRes private val resId: Int) :
11 | ReadOnlyProperty {
12 |
13 | private var binding: T? = null
14 |
15 | override operator fun getValue(thisRef: Activity, property: KProperty<*>): T {
16 | return binding ?: createActivityBinding(thisRef).also { binding = it }
17 | }
18 |
19 | private fun createActivityBinding(activity: Activity): T {
20 | return DataBindingUtil.setContentView(activity, resId)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/toolbar/CollapsibleToolbar.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.toolbar
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.constraintlayout.motion.widget.MotionLayout
6 | import com.google.android.material.appbar.AppBarLayout
7 |
8 | class CollapsibleToolbar @JvmOverloads constructor(
9 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
10 | ) : MotionLayout(context, attrs, defStyleAttr), AppBarLayout.OnOffsetChangedListener {
11 |
12 | override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
13 | progress = -verticalOffset / appBarLayout?.totalScrollRange?.toFloat()!!
14 | }
15 |
16 | override fun onAttachedToWindow() {
17 | super.onAttachedToWindow()
18 | (parent as? AppBarLayout)?.addOnOffsetChangedListener(this)
19 | }
20 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/bottom_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/app/AppDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.app
2 |
3 | import androidx.recyclerview.widget.DiffUtil
4 | import me.tumur.portfolio.repository.database.model.settings.AppModel
5 |
6 | /**
7 | * Callback for calculating the diff between two non-null items in a list.
8 | *
9 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
10 | * list that's been passed to `submitList`.
11 | */
12 |
13 | class AppDiffCallBack: DiffUtil.ItemCallback() {
14 | override fun areItemsTheSame(oldItem: AppModel, newItem: AppModel): Boolean {
15 | return oldItem.title == newItem.title
16 | }
17 |
18 | override fun areContentsTheSame(oldItem: AppModel, newItem: AppModel): Boolean {
19 | return oldItem == newItem
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_map.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/about/AboutDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.about
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 |
6 | /**
7 | * Callback for calculating the diff between two non-null items in a list.
8 | *
9 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
10 | * list that's been passed to `submitList`.
11 | */
12 |
13 | class AboutDiffCallBack: DiffUtil.ItemCallback() {
14 | override fun areItemsTheSame(oldItem: AboutItem, newItem: AboutItem): Boolean {
15 | return oldItem.id == newItem.id
16 | }
17 |
18 | @SuppressLint("DiffUtilEquals")
19 | override fun areContentsTheSame(oldItem: AboutItem, newItem: AboutItem): Boolean {
20 | return oldItem == newItem
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/social/SocialDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.social
2 |
3 | import androidx.recyclerview.widget.DiffUtil
4 | import me.tumur.portfolio.repository.database.model.profile.SocialModel
5 |
6 | /**
7 | * Callback for calculating the diff between two non-null items in a list.
8 | *
9 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
10 | * list that's been passed to `submitList`.
11 | */
12 |
13 | class SocialDiffCallBack: DiffUtil.ItemCallback() {
14 | override fun areItemsTheSame(oldItem: SocialModel, newItem: SocialModel): Boolean {
15 | return oldItem.name == newItem.name
16 | }
17 |
18 | override fun areContentsTheSame(oldItem: SocialModel, newItem: SocialModel): Boolean {
19 | return oldItem == newItem
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rate.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/settings/AppDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.settings
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.settings.AppModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class AppDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List) {
14 | delete()
15 | insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.APP_DELETE)
24 | abstract suspend fun delete()
25 |
26 | /** Get list items */
27 | @Query(DbConstants.APP_GET_LIST_ITEMS)
28 | abstract fun getListItems(): LiveData>
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/settings/AppModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.settings
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.PrimaryKey
7 | import com.google.gson.annotations.SerializedName
8 | import kotlinx.android.parcel.Parcelize
9 | import me.tumur.portfolio.utils.constants.DbConstants
10 |
11 | @Entity(tableName = DbConstants.APP)
12 | @Parcelize
13 | data class AppModel(
14 | @PrimaryKey(autoGenerate = false)
15 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
16 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
17 | @SerializedName(DbConstants.TEXT) @ColumnInfo(name = DbConstants.TEXT) var text: String,
18 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
19 | ): Parcelable
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_profile.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/profile/AboutDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.profile
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.profile.AboutModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class AboutDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List) {
14 | delete()
15 | insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.ABOUT_DELETE)
24 | abstract suspend fun delete()
25 |
26 | /** Get list items */
27 | @Query(DbConstants.ABOUT_GET_LIST_ITEMS)
28 | abstract fun getListItems(id: String): LiveData>
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/profile/SocialDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.profile
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.profile.SocialModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class SocialDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List) {
14 | delete()
15 | insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.SOCIAL_DELETE)
24 | abstract suspend fun delete()
25 |
26 | /** Get list items */
27 | @Query(DbConstants.SOCIAL_GET_LIST_ITEMS)
28 | abstract fun getListItems(id: String): LiveData>
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/task/TaskDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.task
2 |
3 | import androidx.paging.DataSource
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.task.TaskModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class TaskDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List): List {
14 | delete()
15 | return insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.TASK_DELETE)
24 | abstract suspend fun delete()
25 |
26 | /** Get list items */
27 | @Query(DbConstants.TASK_GET_LIST_ITEMS)
28 | abstract fun getListItems(id: String): DataSource.Factory
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/profile/ProfileDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.profile
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.profile.ProfileModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class ProfileDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List) {
14 | delete()
15 | insert(list)
16 | }
17 |
18 | /** Delete */
19 | @Query(DbConstants.PROFILE_DELETE)
20 | abstract suspend fun delete()
21 |
22 | /** Insert */
23 | @Insert(onConflict = OnConflictStrategy.REPLACE)
24 | abstract suspend fun insert(list: List)
25 |
26 | /** Get single item */
27 | @Query(DbConstants.PROFILE_GET_SINGLE_ITEM)
28 | abstract fun getSingleItem(id: String): LiveData
29 |
30 |
31 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_github.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/about/AboutItemViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.about
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemAboutBinding
7 |
8 | /**
9 | * About item viewholder
10 | * */
11 | class AboutItemViewHolder private constructor(val binding: ListItemAboutBinding) : RecyclerView.ViewHolder(binding.root){
12 | fun bind(item: AboutItem.About){
13 | binding.item = item
14 | binding.executePendingBindings()
15 | }
16 |
17 | companion object {
18 | fun from(parent: ViewGroup): AboutItemViewHolder {
19 | val layoutInflater = LayoutInflater.from(parent.context)
20 | val binding = ListItemAboutBinding.inflate(layoutInflater, parent, false)
21 | return AboutItemViewHolder(binding)
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/button/ButtonDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.button
2 |
3 | import androidx.paging.DataSource
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.button.ButtonModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class ButtonDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List): List {
14 | delete()
15 | return insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.BUTTON_DELETE)
24 | abstract suspend fun delete()
25 |
26 | /** Get list items */
27 | @Query(DbConstants.BUTTON_GET_LIST_ITEMS)
28 | abstract fun getListItems(id: String): DataSource.Factory
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/location/LocationDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.location
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.LocationModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class LocationDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List): List {
14 | delete()
15 | return insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.LOCATION_DELETE)
24 | abstract suspend fun delete()
25 |
26 |
27 | /** Get single item */
28 | @Query(DbConstants.LOCATION_GET_SINGLE_ITEM)
29 | abstract fun getSingleItem(id: String): LiveData
30 |
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/category/CategoryDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.category
2 |
3 | import androidx.paging.DataSource
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.category.CategoryModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 | @Dao
9 | abstract class CategoryDao {
10 |
11 | /** Update */
12 | @Transaction
13 | open suspend fun update(list: List): List {
14 | delete()
15 | return insert(list)
16 | }
17 |
18 | /** Insert */
19 | @Insert(onConflict = OnConflictStrategy.REPLACE)
20 | abstract suspend fun insert(list: List): List
21 |
22 | /** Delete */
23 | @Query(DbConstants.CATEGORY_DELETE)
24 | abstract suspend fun delete()
25 |
26 | /** Get list items */
27 | @Query(DbConstants.CATEGORY_GET_LIST_ITEMS)
28 | abstract fun getListItems(type: Int): DataSource.Factory
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/task/TaskDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience.task
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.task.TaskModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class TaskDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: TaskModel, newItem: TaskModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: TaskModel, newItem: TaskModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/about/AboutHeaderViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.about
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemAboutHeaderBinding
7 |
8 | /**
9 | * About item's header viewholder
10 | * */
11 | class AboutHeaderViewHolder private constructor(val binding: ListItemAboutHeaderBinding) : RecyclerView.ViewHolder(binding.root){
12 | fun bind(header: AboutItem.Header){
13 | binding.header = header
14 | binding.executePendingBindings()
15 | }
16 |
17 | companion object {
18 | fun from(parent: ViewGroup): AboutHeaderViewHolder {
19 | val layoutInflater = LayoutInflater.from(parent.context)
20 | val binding = ListItemAboutHeaderBinding.inflate(layoutInflater, parent, false)
21 | return AboutHeaderViewHolder(binding)
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_link.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/favorite/FavoriteDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.favorite
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.favorite.FavoriteModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class FavoriteDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: FavoriteModel, newItem: FavoriteModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: FavoriteModel, newItem: FavoriteModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/button/ButtonDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.button.ButtonModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class ButtonDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: ButtonModel, newItem: ButtonModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: ButtonModel, newItem: ButtonModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/task/TaskModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.task
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 |
12 | @Entity(tableName = DbConstants.TASKS, indices = [Index(value = [DbConstants.ID], unique = true)])
13 | @Parcelize
14 | data class TaskModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
18 | @SerializedName(DbConstants.TASK) @ColumnInfo(name = DbConstants.TASK) var task: String,
19 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
20 | ): Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/PortfolioDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.portfolio.PortfolioModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class PortfolioDiffCallBack: DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: PortfolioModel, newItem: PortfolioModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: PortfolioModel, newItem: PortfolioModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/theme/ThemeHelper.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.theme
2 |
3 | import android.os.Build
4 | import androidx.appcompat.app.AppCompatDelegate
5 | import me.tumur.portfolio.utils.constants.Constants
6 |
7 | object ThemeHelper {
8 | fun applyTheme(themePref: String) {
9 | when (themePref) {
10 | Constants.THEME_LIGHT -> {
11 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
12 | }
13 | Constants.THEME_DARK -> {
14 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
15 | }
16 | else -> {
17 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
18 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
19 | } else {
20 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)
21 | }
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/profile/AboutModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.profile
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.Index
6 | import androidx.room.PrimaryKey
7 | import com.google.gson.annotations.SerializedName
8 | import me.tumur.portfolio.utils.constants.DbConstants
9 |
10 | @Entity(tableName = DbConstants.ABOUT, indices = [Index(value = [DbConstants.ID], unique = true)])
11 | data class AboutModel(
12 | @PrimaryKey(autoGenerate = false)
13 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
14 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
15 | @SerializedName(DbConstants.HEADER) @ColumnInfo(name = DbConstants.HEADER) var header: String,
16 | @SerializedName(DbConstants.TEXT) @ColumnInfo(name = DbConstants.TEXT) var text: String,
17 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
18 | )
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/ExperienceDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.experience.ExperienceModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class ExperienceDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: ExperienceModel, newItem: ExperienceModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: ExperienceModel, newItem: ExperienceModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/resource/ResourceDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience.resource
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.resource.ResourceModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class ResourceDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: ResourceModel, newItem: ResourceModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: ResourceModel, newItem: ResourceModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/task/TaskViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience.task
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemTaskBinding
7 | import me.tumur.portfolio.repository.database.model.task.TaskModel
8 |
9 | /**
10 | * Task viewholder
11 | * */
12 | class TaskViewHolder private constructor(val binding: ListItemTaskBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: TaskModel?) {
15 | binding.item = item
16 | binding.executePendingBindings()
17 | }
18 |
19 | companion object {
20 | fun from(parent: ViewGroup): TaskViewHolder {
21 | val layoutInflater = LayoutInflater.from(parent.context)
22 | val binding = ListItemTaskBinding.inflate(layoutInflater, parent, false)
23 | return TaskViewHolder(binding)
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/category/CategoryDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.category
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.category.CategoryModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class CategoryDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: CategoryModel, newItem: CategoryModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/screenshot/ScreenShotDiffCallBack.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.screenshot
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.recyclerview.widget.DiffUtil
5 | import me.tumur.portfolio.repository.database.model.screenshot.ScreenShotModel
6 |
7 | /**
8 | * Callback for calculating the diff between two non-null items in a list.
9 | *
10 | * Used by ListAdapter or PagedListAdapter to calculate the minimum number of changes between and old list and a new
11 | * list that's been passed to `submitList`.
12 | */
13 |
14 | class ScreenShotDiffCallBack : DiffUtil.ItemCallback() {
15 | override fun areItemsTheSame(oldItem: ScreenShotModel, newItem: ScreenShotModel): Boolean {
16 | return oldItem.id == newItem.id
17 | }
18 |
19 | @SuppressLint("DiffUtilEquals")
20 | override fun areContentsTheSame(oldItem: ScreenShotModel, newItem: ScreenShotModel): Boolean {
21 | return oldItem == newItem
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_empty.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fab_profile.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/app/AppViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.app
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemDialogAppInfoBinding
7 | import me.tumur.portfolio.repository.database.model.settings.AppModel
8 |
9 | /**
10 | * Constructor of ViewHolder
11 | * */
12 | class AppViewHolder private constructor(val binding: ListItemDialogAppInfoBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 |
15 | fun bind(appInfoItem: AppModel){
16 | binding.item = appInfoItem
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): AppViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemDialogAppInfoBinding.inflate(layoutInflater, parent, false)
24 | return AppViewHolder(binding)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/LocationModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 |
12 | @Entity(tableName = DbConstants.LOCATION, indices = [Index(value = [DbConstants.ID], unique = true)])
13 | @Parcelize
14 | data class LocationModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
18 | @SerializedName(DbConstants.LATITUDE) @ColumnInfo(name = DbConstants.LATITUDE) var latitude: Double? = null,
19 | @SerializedName(DbConstants.LONGITUDE) @ColumnInfo(name = DbConstants.LONGITUDE) var longitude: Double? = null
20 | ) : Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/category/CategoryViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.category
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemCategoryBinding
7 | import me.tumur.portfolio.repository.database.model.category.CategoryModel
8 |
9 | /**
10 | * Category viewholder
11 | * */
12 | class CategoryViewHolder private constructor(val binding: ListItemCategoryBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: CategoryModel?) {
15 | binding.item = item
16 | binding.executePendingBindings()
17 | }
18 |
19 | companion object {
20 | fun from(parent: ViewGroup): CategoryViewHolder {
21 | val layoutInflater = LayoutInflater.from(parent.context)
22 | val binding = ListItemCategoryBinding.inflate(layoutInflater, parent, false)
23 | return CategoryViewHolder(binding)
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/profile_menu.xml:
--------------------------------------------------------------------------------
1 |
3 | -
10 |
11 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 0dp
4 | 1dp
5 | 2dp
6 | 20dp
7 | 4dp
8 | 230dp
9 | 480dp
10 | 80
11 | 0
12 | 5sp
13 | 4sp
14 | 10sp
15 | 12sp
16 | 14sp
17 | 15sp
18 | 16sp
19 | 18sp
20 | 20sp
21 | 22sp
22 | 24sp
23 | 26sp
24 | 16dp
25 | 8dp
26 | 4dp
27 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/resource/ResourceDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.resource
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.paging.DataSource
5 | import androidx.room.*
6 | import me.tumur.portfolio.repository.database.model.resource.ResourceModel
7 | import me.tumur.portfolio.utils.constants.DbConstants
8 |
9 | @Dao
10 | abstract class ResourceDao {
11 |
12 | /** Update */
13 | @Transaction
14 | open suspend fun update(list: List) {
15 | delete()
16 | insert(list)
17 | }
18 |
19 | /** Delete */
20 | @Query(DbConstants.RESOURCE_DELETE)
21 | abstract suspend fun delete()
22 |
23 | /** Insert */
24 | @Insert(onConflict = OnConflictStrategy.REPLACE)
25 | abstract suspend fun insert(list: List)
26 |
27 | /** Get list items */
28 | @Query(DbConstants.RESOURCE_GET_LIST_ITEMS)
29 | abstract fun getListItems(id: String): DataSource.Factory
30 |
31 | /** Check table */
32 | @Query(DbConstants.RESOURCE_CHECK)
33 | abstract fun check(id: String): LiveData
34 |
35 |
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/profile/SocialModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.profile
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 |
12 | @Entity(tableName = DbConstants.SOCIAL, indices = [Index(value = [DbConstants.ID, DbConstants.OWNER_ID], unique = true)])
13 | @Parcelize
14 | data class SocialModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
18 | @SerializedName(DbConstants.NAME) @ColumnInfo(name = DbConstants.NAME) var name: String,
19 | @SerializedName(DbConstants.URL) @ColumnInfo(name = DbConstants.URL) var url: String,
20 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
21 | ): Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/favorite/FavoriteViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.favorite
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemFavoriteBinding
7 | import me.tumur.portfolio.repository.database.model.favorite.FavoriteModel
8 |
9 | /**
10 | * Favorite item viewholder
11 | * */
12 | class FavoriteViewHolder private constructor(val binding: ListItemFavoriteBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: FavoriteModel?, clickListener: FavoriteClickListener) {
15 | binding.clickListener = clickListener
16 | binding.item = item
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): FavoriteViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemFavoriteBinding.inflate(layoutInflater, parent, false)
24 | return FavoriteViewHolder(binding)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_privacy.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/PortfolioViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemPortfolioBinding
7 | import me.tumur.portfolio.repository.database.model.portfolio.PortfolioModel
8 |
9 | /**
10 | * Portfolio item viewholder
11 | * */
12 | class PortfolioViewHolder private constructor(val binding: ListItemPortfolioBinding) : RecyclerView.ViewHolder(binding.root){
13 | fun bind(item: PortfolioModel?, clickListener: PortfolioClickListener){
14 | binding.clickListener = clickListener
15 | binding.item = item
16 | binding.executePendingBindings()
17 | }
18 |
19 | companion object {
20 | fun from(parent: ViewGroup): PortfolioViewHolder {
21 | val layoutInflater = LayoutInflater.from(parent.context)
22 | val binding = ListItemPortfolioBinding.inflate(layoutInflater, parent, false)
23 | return PortfolioViewHolder(binding)
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/welcome/WelcomeModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.welcome
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.Index
6 | import androidx.room.PrimaryKey
7 | import com.google.gson.annotations.SerializedName
8 | import me.tumur.portfolio.utils.constants.DbConstants
9 |
10 | @Entity(tableName = DbConstants.WELCOME, indices = [Index(value = [DbConstants.ID], unique = true)])
11 | data class WelcomeModel(
12 | @PrimaryKey(autoGenerate = false)
13 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
14 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
15 | @SerializedName(DbConstants.SUB_TITLE) @ColumnInfo(name = DbConstants.SUB_TITLE) var subTitle: String,
16 | @SerializedName(DbConstants.TEXT) @ColumnInfo(name = DbConstants.TEXT) var text: String,
17 | @SerializedName(DbConstants.IMAGE_DESCRIPTION) @ColumnInfo(name = DbConstants.IMAGE_DESCRIPTION) val imageDescription: String,
18 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
19 | )
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/button/ButtonNormalViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemButtonBinding
7 | import me.tumur.portfolio.repository.database.model.button.ButtonModel
8 |
9 | /**
10 | * Button normal viewholder
11 | * */
12 | class ButtonNormalViewHolder private constructor(val binding: ListItemButtonBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: ButtonModel, clickListener: ButtonClickListener) {
15 | binding.clickListener = clickListener
16 | binding.button = item
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): ButtonNormalViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemButtonBinding.inflate(layoutInflater, parent, false)
24 | return ButtonNormalViewHolder(binding)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_privacy.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/screenshot/ScreenShotModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.screenshot
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 |
12 | @Entity(tableName = DbConstants.SCREENSHOT, indices = [Index(value = [DbConstants.ID], unique = true)])
13 | @Parcelize
14 | data class ScreenShotModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
18 | @SerializedName(DbConstants.URL) @ColumnInfo(name = DbConstants.URL) var url: String,
19 | @SerializedName(DbConstants.DESCRIPTION) @ColumnInfo(name = DbConstants.IMAGE_DESCRIPTION) var imageDescription: String,
20 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
21 | ) : Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/ExperienceViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemExperienceBinding
7 | import me.tumur.portfolio.repository.database.model.experience.ExperienceModel
8 |
9 | /**
10 | * Experience item viewholder
11 | * */
12 | class ExperienceViewHolder private constructor(val binding: ListItemExperienceBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: ExperienceModel?, clickListener: ExperienceClickListener) {
15 | binding.clickListener = clickListener
16 | binding.item = item
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): ExperienceViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemExperienceBinding.inflate(layoutInflater, parent, false)
24 | return ExperienceViewHolder(binding)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/social/SocialViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.social
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemBsSocialBinding
7 | import me.tumur.portfolio.repository.database.model.profile.SocialModel
8 |
9 | /**
10 | * Constructor of ViewHolder
11 | * */
12 | class SocialViewHolder private constructor(val binding: ListItemBsSocialBinding) : RecyclerView.ViewHolder(binding.root){
13 |
14 | fun bind(socialItem: SocialModel, clickListener: SocialClickListener){
15 | binding.clickListener = clickListener
16 | binding.social = socialItem
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): SocialViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemBsSocialBinding.inflate(layoutInflater, parent, false)
24 | return SocialViewHolder(
25 | binding
26 | )
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_read_more.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
7 |
9 |
11 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/button/ButtonOutlineViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemButtonOutlineBinding
7 | import me.tumur.portfolio.repository.database.model.button.ButtonModel
8 |
9 | /**
10 | * Button normal viewholder
11 | * */
12 | class ButtonOutlineViewHolder private constructor(val binding: ListItemButtonOutlineBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: ButtonModel, clickListener: ButtonClickListener) {
15 | binding.clickListener = clickListener
16 | binding.button = item
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): ButtonOutlineViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemButtonOutlineBinding.inflate(layoutInflater, parent, false)
24 | return ButtonOutlineViewHolder(binding)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/screenshot/ScreenShotViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.screenshot
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemScreenshotBinding
7 | import me.tumur.portfolio.repository.database.model.screenshot.ScreenShotModel
8 |
9 | /**
10 | * Screenshot viewholder
11 | * */
12 | class ScreenShotViewHolder private constructor(val binding: ListItemScreenshotBinding) :
13 | RecyclerView.ViewHolder(binding.root) {
14 | fun bind(item: ScreenShotModel?, clickListener: ScreenShotClickListener) {
15 | binding.clickListener = clickListener
16 | binding.item = item
17 | binding.executePendingBindings()
18 | }
19 |
20 | companion object {
21 | fun from(parent: ViewGroup): ScreenShotViewHolder {
22 | val layoutInflater = LayoutInflater.from(parent.context)
23 | val binding = ListItemScreenshotBinding.inflate(layoutInflater, parent, false)
24 | return ScreenShotViewHolder(binding)
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wifi.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/welcome/pager/WelcomePagerViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.welcome.pager
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import me.tumur.portfolio.repository.database.model.welcome.WelcomeModel
7 |
8 | class WelcomePagerViewModel : ViewModel() {
9 |
10 | /** VARIABLES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
11 |
12 | /** Pager' position */
13 | private val _position = MutableLiveData()
14 | val position: LiveData = _position
15 |
16 | /** Screen's data */
17 | private val _data = MutableLiveData()
18 | val data: LiveData = _data
19 |
20 | /** FUNCTIONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21 |
22 | /**
23 | * Set pager's position
24 | * */
25 | fun setPosition(position: Int){
26 | _position.value = position
27 | }
28 |
29 | /**
30 | * Set screen's data
31 | * */
32 | fun setData(model: WelcomeModel){
33 | _data.apply { value = model }
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/extensions/isNetworkAvailable.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.extensions
2 |
3 | import android.Manifest
4 | import android.content.Context
5 | import android.net.ConnectivityManager
6 | import android.net.NetworkCapabilities
7 | import android.os.Build
8 | import androidx.annotation.RequiresPermission
9 |
10 | /**
11 | * Checks network access
12 | */
13 | @RequiresPermission(value = Manifest.permission.ACCESS_NETWORK_STATE)
14 | fun Any.isNetworkAvailable(context: Context): Boolean {
15 | val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
16 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
17 | val nw = connectivityManager.activeNetwork ?: return false
18 | val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
19 | return when {
20 | actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
21 | actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
22 | else -> false
23 | }
24 | } else {
25 | val nwInfo = connectivityManager.activeNetwork ?: return false
26 | return nwInfo.isNetworkAvailable(context)
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/button/ButtonModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.button
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 |
12 | @Entity(tableName = DbConstants.BUTTON, indices = [Index(value = [DbConstants.ID], unique = true)])
13 | @Parcelize
14 | data class ButtonModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
18 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
19 | @SerializedName(DbConstants.URL) @ColumnInfo(name = DbConstants.URL) var url: String,
20 | @SerializedName(DbConstants.TYPE) @ColumnInfo(name = DbConstants.TYPE) var type: String,
21 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
22 | ): Parcelable
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_experience.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
7 |
8 |
9 |
11 |
13 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/experience/ExperienceDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.experience
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.paging.DataSource
5 | import androidx.room.*
6 | import me.tumur.portfolio.repository.database.model.experience.ExperienceModel
7 | import me.tumur.portfolio.utils.constants.DbConstants
8 |
9 | @Dao
10 | abstract class ExperienceDao {
11 |
12 | /** Update */
13 | @Transaction
14 | open suspend fun update(list: List): List {
15 | delete()
16 | return insert(list)
17 | }
18 |
19 | /** Insert */
20 | @Insert(onConflict = OnConflictStrategy.REPLACE)
21 | abstract suspend fun insert(list: List): List
22 |
23 | /** Delete */
24 | @Query(DbConstants.EXPERIENCE_DELETE)
25 | abstract suspend fun delete()
26 |
27 | /** Get list items */
28 | @Query(DbConstants.EXPERIENCE_GET_LIST_ITEMS)
29 | abstract fun getListItems(id: String): DataSource.Factory
30 |
31 |
32 | /** Get single item */
33 | @Query(DbConstants.EXPERIENCE_GET_SINGLE_ITEM)
34 | abstract fun getSingleItem(id: String): LiveData
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/screenshot/ScreenShotDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.screenshot
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.paging.DataSource
5 | import androidx.room.*
6 | import me.tumur.portfolio.repository.database.model.screenshot.ScreenShotModel
7 | import me.tumur.portfolio.utils.constants.DbConstants
8 |
9 | @Dao
10 | abstract class ScreenShotDao {
11 |
12 | /** Update */
13 | @Transaction
14 | open suspend fun update(list: List): List {
15 | delete()
16 | return insert(list)
17 | }
18 |
19 | /** Insert */
20 | @Insert(onConflict = OnConflictStrategy.REPLACE)
21 | abstract suspend fun insert(list: List): List
22 |
23 | /** Delete */
24 | @Query(DbConstants.SCREENSHOT_DELETE)
25 | abstract suspend fun delete()
26 |
27 | /** Get paged list items */
28 | @Query(DbConstants.SCREENSHOT_GET_LIST_ITEMS)
29 | abstract fun getPagedListItems(id: String): DataSource.Factory
30 |
31 | /** Get list items */
32 | @Query(DbConstants.SCREENSHOT_GET_LIST_ITEMS)
33 | abstract fun getListItems(id: String): LiveData>
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/welcome/WelcomeDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.welcome
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import me.tumur.portfolio.repository.database.model.welcome.WelcomeModel
6 | import me.tumur.portfolio.utils.constants.DbConstants
7 |
8 |
9 | @Dao
10 | abstract class WelcomeDao {
11 |
12 | /** Update */
13 | @Transaction
14 | open suspend fun update(list: List): List {
15 | delete()
16 | return insert(list)
17 | }
18 |
19 | /** Check */
20 | @Query(DbConstants.WELCOME_CHECK)
21 | abstract suspend fun check(): Int
22 |
23 | /** Insert */
24 | @Insert(onConflict = OnConflictStrategy.REPLACE)
25 | abstract suspend fun insert(data: List): List
26 |
27 | /** Delete */
28 | @Query(DbConstants.WELCOME_DELETE)
29 | abstract suspend fun delete()
30 |
31 | /** Get list items */
32 | @Query(DbConstants.WELCOME_GET_LIST_ITEMS)
33 | abstract fun getListItems(): LiveData>
34 |
35 | /** Get single item */
36 | @Query(DbConstants.WELCOME_GET_SINGLE_ITEM)
37 | abstract fun getSingleItem(id: String): LiveData
38 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 |
12 |
16 |
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/side_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
12 |
16 |
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/category/CategoryModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.category
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 |
12 | @Entity(tableName = DbConstants.CATEGORY, indices = [Index(value = [DbConstants.ID], unique = true)])
13 | @Parcelize
14 | data class CategoryModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
18 | @SerializedName(DbConstants.TYPE) @ColumnInfo(name = DbConstants.TYPE) var type: Int,
19 | @SerializedName(DbConstants.ICON) @ColumnInfo(name = DbConstants.ICON) var icon: String,
20 | @SerializedName(DbConstants.ICON_DESCRIPTION) @ColumnInfo(name = DbConstants.ICON_DESCRIPTION) var iconDescription: String,
21 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
22 | ) : Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/resource/ResourceViewHolder.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience.resource
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.databinding.ListItemResourceBinding
7 | import me.tumur.portfolio.repository.database.model.resource.ResourceModel
8 | import me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button.ButtonClickListener
9 |
10 | /**
11 | * Resource item viewholder
12 | * */
13 | class ResourceViewHolder private constructor(val binding: ListItemResourceBinding) :
14 | RecyclerView.ViewHolder(binding.root) {
15 | fun bind(item: ResourceModel?, clickListener: ButtonClickListener) {
16 | binding.clickListener = clickListener
17 | binding.item = item
18 | binding.executePendingBindings()
19 | }
20 |
21 | companion object {
22 | fun from(parent: ViewGroup): ResourceViewHolder {
23 | val layoutInflater = LayoutInflater.from(parent.context)
24 | val binding = ListItemResourceBinding.inflate(layoutInflater, parent, false)
25 | return ResourceViewHolder(binding)
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_avatar_placeholder.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
7 |
9 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_profile_placeholder.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
7 |
9 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/settings/dialog/AppDialogViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.settings.dialog
2 |
3 | import androidx.lifecycle.*
4 | import kotlinx.coroutines.Dispatchers
5 | import me.tumur.portfolio.repository.database.dao.settings.AppDao
6 | import org.koin.core.KoinComponent
7 | import org.koin.core.inject
8 |
9 | class AppDialogViewModel: ViewModel(), KoinComponent{
10 |
11 | /** VARIABLES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 |
13 | /** RepositoryImp */
14 | private val appDao: AppDao by inject()
15 |
16 | /** Profile data */
17 | val appInfo = liveData(context = viewModelScope.coroutineContext + Dispatchers.IO){
18 | emitSource(appDao.getListItems())
19 | }
20 |
21 | /** Close button on click */
22 | private val _closeButtonOnClick = MutableLiveData().apply { value = false }
23 | val closeButtonOnClick: LiveData = _closeButtonOnClick
24 |
25 | /** FUNCTIONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 |
27 | /**
28 | * Set close button onClick event
29 | * */
30 | fun setCloseButtonOnClick(status: Boolean){
31 | _closeButtonOnClick.apply { value = status }
32 | }
33 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 | kapt.incremental.apt=true
23 | GOOGLE_MAPS_API_KEY=AIzaSyDJrKxFSF3DIvtWmlTTQQKf1OvYsd9YDtY
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/screen_profile_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_refresh.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_experience.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/preference_category_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
26 |
27 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Android
17 |
18 |
19 | CorrectnessLintAndroid
20 |
21 |
22 | General
23 |
24 |
25 | Kotlin
26 |
27 |
28 | LintAndroid
29 |
30 |
31 | PerformanceLintAndroid
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 |
11 |
15 |
19 |
23 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/portfolio/PortfolioDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.portfolio
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.paging.DataSource
5 | import androidx.room.*
6 | import me.tumur.portfolio.repository.database.model.portfolio.PortfolioModel
7 | import me.tumur.portfolio.utils.constants.DbConstants
8 |
9 | @Dao
10 | abstract class PortfolioDao {
11 |
12 | /** Update */
13 | @Transaction
14 | open suspend fun update(list: List): List {
15 | delete()
16 | return insert(list)
17 | }
18 |
19 | /** Insert */
20 | @Insert(onConflict = OnConflictStrategy.REPLACE)
21 | abstract suspend fun insert(list: List): List
22 |
23 | /** Delete */
24 | @Query(DbConstants.PORTFOLIO_DELETE)
25 | abstract suspend fun delete()
26 |
27 | /** Get list items */
28 | @Query(DbConstants.PORTFOLIO_GET_LIST_ITEMS)
29 | abstract fun getListItems(id: String): DataSource.Factory
30 |
31 |
32 | /** Get single item */
33 | @Query(DbConstants.PORTFOLIO_GET_SINGLE_ITEM)
34 | abstract fun getSingleItem(id: String): LiveData
35 |
36 | // /** Search by query */
37 | // @Query(DbConstants.GET_PORTFOLIO_BY_QUERY)
38 | // abstract fun getByQuery(query: String): LiveData>
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/preference_category_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/profile/ProfileModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.profile
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.Index
6 | import androidx.room.PrimaryKey
7 | import com.google.gson.annotations.SerializedName
8 | import me.tumur.portfolio.utils.constants.DbConstants
9 |
10 | @Entity(
11 | tableName = DbConstants.PROFILE,
12 | indices = [Index(value = [DbConstants.ID, DbConstants.NAME], unique = true)]
13 | )
14 | data class ProfileModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @SerializedName(DbConstants.GREETING) @ColumnInfo(name = DbConstants.GREETING) var greeting: String,
18 | @SerializedName(DbConstants.NAME) @ColumnInfo(name = DbConstants.NAME) var name: String,
19 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
20 | @SerializedName(DbConstants.IMAGE) @ColumnInfo(name = DbConstants.IMAGE) var image: String,
21 | @SerializedName(DbConstants.IMAGE_DESCRIPTION) @ColumnInfo(name = DbConstants.IMAGE_DESCRIPTION) var imageDescription: String,
22 | @SerializedName(DbConstants.EMAIL) @ColumnInfo(name = DbConstants.EMAIL) var email: String,
23 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
24 | )
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_globe.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/task/TaskAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience.task
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.task.TaskModel
7 |
8 | /**
9 | * An adapter that provides a list of [TaskModel] to a [RecyclerView]
10 | * */
11 |
12 | class TaskAdapter : PagedListAdapter(TaskDiffCallBack()) {
13 |
14 | /**
15 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [TaskViewHolder]
16 | *
17 | * A [TaskViewHolder] holds the view for the [RecyclerView] as well as providing information
18 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
19 | * */
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
21 | return TaskViewHolder.from(parent)
22 | }
23 |
24 | /**
25 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
26 | *
27 | * The [TaskViewHolder] passed may be recycled so make sure that this sets any properties
28 | * that may be have been set previously
29 | * */
30 | override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
31 | holder.bind(getItem(position))
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_email.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/app/AppAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.app
2 |
3 | import android.view.ViewGroup
4 | import androidx.recyclerview.widget.ListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.settings.AppModel
7 |
8 | /**
9 | * An adapter that provides a list of [AppModel] to a [RecyclerView]
10 | * */
11 |
12 | class AppAdapter: ListAdapter(AppDiffCallBack()) {
13 |
14 | /**
15 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [AppViewHolder]
16 | *
17 | * A [AppViewHolder] holds the view for the [RecyclerView] as well as providing information
18 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
19 | * */
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
21 | return AppViewHolder.from(parent)
22 | }
23 |
24 | /**
25 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
26 | *
27 | * The [AppViewHolder] passed may be recycled so make sure that this sets any properties
28 | * that may be have been set previously
29 | * */
30 | override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
31 | val appInfoItem = getItem(position)
32 | holder.bind(appInfoItem)
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_logo.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
13 |
17 |
21 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_settings.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/category/CategoryAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.category
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.category.CategoryModel
7 |
8 | /**
9 | * An adapter that provides a list of [CategoryModel] to a [RecyclerView]
10 | * */
11 |
12 | class CategoryAdapter : PagedListAdapter(CategoryDiffCallBack()) {
13 |
14 | /**
15 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [CategoryViewHolder]
16 | *
17 | * A [CategoryViewHolder] holds the view for the [RecyclerView] as well as providing information
18 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
19 | * */
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder {
21 | return CategoryViewHolder.from(parent)
22 | }
23 |
24 | /**
25 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
26 | *
27 | * The [CategoryViewHolder] passed may be recycled so make sure that this sets any properties
28 | * that may be have been set previously
29 | * */
30 | override fun onBindViewHolder(holder: CategoryViewHolder, position: Int) {
31 | holder.bind(getItem(position))
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_category_code.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
24 |
30 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_no_connection.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "852832723346",
4 | "firebase_url": "https://portfolio-app-147b5.firebaseio.com",
5 | "project_id": "portfolio-app-147b5",
6 | "storage_bucket": "portfolio-app-147b5.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:852832723346:android:c8b206b00866c4fa",
12 | "android_client_info": {
13 | "package_name": "me.tumur.portfolio"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "852832723346-ddic85s6rk4gb9b9e7t6c85ig7733n0s.apps.googleusercontent.com",
19 | "client_type": 1,
20 | "android_info": {
21 | "package_name": "me.tumur.portfolio",
22 | "certificate_hash": "d7ad4634a38255ed8eda9e62be06a518d53f28ea"
23 | }
24 | },
25 | {
26 | "client_id": "852832723346-ldtgti7i46pk2fe8tbc9b2k3ak7bun1s.apps.googleusercontent.com",
27 | "client_type": 3
28 | }
29 | ],
30 | "api_key": [
31 | {
32 | "current_key": "AIzaSyB2X5f4wo6QC9Pgrz3mcms5-Z0n0gWQx-M"
33 | }
34 | ],
35 | "services": {
36 | "appinvite_service": {
37 | "other_platform_oauth_client": [
38 | {
39 | "client_id": "852832723346-ldtgti7i46pk2fe8tbc9b2k3ak7bun1s.apps.googleusercontent.com",
40 | "client_type": 3
41 | }
42 | ]
43 | }
44 | }
45 | }
46 | ],
47 | "configuration_version": "1"
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/social/SocialAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.social
2 |
3 | import android.view.ViewGroup
4 | import androidx.recyclerview.widget.ListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.profile.SocialModel
7 |
8 | /**
9 | * An adapter that provides a list of [SocialModel] to a [RecyclerView]
10 | * */
11 |
12 | class SocialAdapter(private val clickListener: SocialClickListener): ListAdapter(SocialDiffCallBack()) {
13 |
14 | /**
15 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [SocialViewHolder]
16 | *
17 | * A [SocialViewHolder] holds the view for the [RecyclerView] as well as providing information
18 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
19 | * */
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SocialViewHolder {
21 | return SocialViewHolder.from(parent)
22 | }
23 |
24 | /**
25 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
26 | *
27 | * The [SocialViewHolder] passed may be recycled so make sure that this sets any properties
28 | * that may be have been set previously
29 | * */
30 | override fun onBindViewHolder(holder: SocialViewHolder, position: Int) {
31 | val socialItem = getItem(position)
32 | holder.bind(socialItem, clickListener)
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/favorite/FavoriteAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.favorite
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.favorite.FavoriteModel
7 |
8 | /**
9 | * An adapter that provides a list of [FavoriteModel] to a [RecyclerView]
10 | * */
11 |
12 | class FavoriteAdapter(private val clickListener: FavoriteClickListener) :
13 | PagedListAdapter(FavoriteDiffCallBack()) {
14 |
15 | /**
16 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [FavoriteViewHolder]
17 | *
18 | * A [FavoriteViewHolder] holds the view for the [RecyclerView] as well as providing information
19 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
20 | * */
21 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavoriteViewHolder {
22 | return FavoriteViewHolder.from(parent)
23 | }
24 |
25 | /**
26 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
27 | *
28 | * The [FavoriteViewHolder] passed may be recycled so make sure that this sets any properties
29 | * that may be have been set previously
30 | * */
31 | override fun onBindViewHolder(holder: FavoriteViewHolder, position: Int) {
32 | val favoriteItem = getItem(position)
33 | holder.bind(favoriteItem, clickListener)
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/resource/ResourceModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.resource
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import com.google.gson.annotations.SerializedName
9 | import kotlinx.android.parcel.Parcelize
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 | import java.util.*
12 |
13 | @Entity(tableName = DbConstants.RESOURCE, indices = [Index(value = [DbConstants.ID], unique = true)])
14 | @Parcelize
15 | data class ResourceModel(
16 | @PrimaryKey(autoGenerate = false)
17 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
18 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
19 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
20 | @SerializedName(DbConstants.IMAGE) @ColumnInfo(name = DbConstants.IMAGE) var image: String,
21 | @SerializedName(DbConstants.IMAGE_DESCRIPTION) @ColumnInfo(name = DbConstants.IMAGE_DESCRIPTION) var imageDescription: String,
22 | @SerializedName(DbConstants.DATE_FROM) @ColumnInfo(name = DbConstants.DATE_FROM) var dateFrom: Date,
23 | @SerializedName(DbConstants.DATE_TO) @ColumnInfo(name = DbConstants.DATE_TO) var dateTo: Date,
24 | @SerializedName(DbConstants.URL) @ColumnInfo(name = DbConstants.URL) var url: String?,
25 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
26 | ) : Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/PortfolioAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.portfolio.PortfolioModel
7 |
8 | /**
9 | * An adapter that provides a list of [PortfolioModel] to a [RecyclerView]
10 | * */
11 |
12 | class PortfolioAdapter(private val clickListener: PortfolioClickListener) : PagedListAdapter(PortfolioDiffCallBack()) {
13 |
14 | /**
15 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [PortfolioViewHolder]
16 | *
17 | * A [PortfolioViewHolder] holds the view for the [RecyclerView] as well as providing information
18 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
19 | * */
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PortfolioViewHolder {
21 | return PortfolioViewHolder.from(parent)
22 | }
23 |
24 | /**
25 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
26 | *
27 | * The [PortfolioViewHolder] passed may be recycled so make sure that this sets any properties
28 | * that may be have been set previously
29 | * */
30 | override fun onBindViewHolder(holder: PortfolioViewHolder, position: Int) {
31 | val portfolioItem = getItem(position)
32 | holder.bind(portfolioItem, clickListener)
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/portfolio/screenshot/ScreenShotAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.screenshot
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.screenshot.ScreenShotModel
7 |
8 | /**
9 | * An adapter that provides a list of [ScreenShotModel] to a [RecyclerView]
10 | * */
11 |
12 | class ScreenShotAdapter(private val clickListener: ScreenShotClickListener) :
13 | PagedListAdapter(ScreenShotDiffCallBack()) {
14 |
15 | /**
16 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [ScreenShotViewHolder]
17 | *
18 | * A [ScreenShotViewHolder] holds the view for the [RecyclerView] as well as providing information
19 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
20 | * */
21 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ScreenShotViewHolder {
22 | return ScreenShotViewHolder.from(parent)
23 | }
24 |
25 | /**
26 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
27 | *
28 | * The [ScreenShotViewHolder] passed may be recycled so make sure that this sets any properties
29 | * that may be have been set previously
30 | * */
31 | override fun onBindViewHolder(holder: ScreenShotViewHolder, position: Int) {
32 | holder.bind(getItem(position), clickListener)
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_hand_waving.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/ExperienceAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.experience.ExperienceModel
7 |
8 | /**
9 | * An adapter that provides a list of [ExperienceModel] to a [RecyclerView]
10 | * */
11 |
12 | class ExperienceAdapter(private val clickListener: ExperienceClickListener) :
13 | PagedListAdapter(
14 | ExperienceDiffCallBack()
15 | ) {
16 |
17 | /**
18 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [ExperienceViewHolder]
19 | *
20 | * A [ExperienceViewHolder] holds the view for the [RecyclerView] as well as providing information
21 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
22 | * */
23 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExperienceViewHolder {
24 | return ExperienceViewHolder.from(parent)
25 | }
26 |
27 | /**
28 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
29 | *
30 | * The [ExperienceViewHolder] passed may be recycled so make sure that this sets any properties
31 | * that may be have been set previously
32 | * */
33 | override fun onBindViewHolder(holder: ExperienceViewHolder, position: Int) {
34 | val experienceItem = getItem(position)
35 | holder.bind(experienceItem, clickListener)
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/portfolio/detail/preview/pager/PreviewPagerViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.portfolio.detail.preview.pager
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import me.tumur.portfolio.repository.database.model.screenshot.ScreenShotModel
7 | import me.tumur.portfolio.utils.state.PreviewState
8 | import me.tumur.portfolio.utils.state.ProgressBar
9 | import org.koin.core.KoinComponent
10 |
11 | class PreviewPagerViewModel : ViewModel(), KoinComponent {
12 |
13 | /** VARIABLES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
14 |
15 | /** Position */
16 | private val _position = MutableLiveData()
17 | val position: LiveData = _position
18 |
19 | /** Screenshot */
20 | private val _data = MutableLiveData()
21 | val data: LiveData = _data
22 |
23 | /** State */
24 | private val _state = MutableLiveData().apply { value = ProgressBar }
25 | val state: LiveData = _state
26 |
27 | /** FUNCTIONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
28 |
29 | /**
30 | * Set position
31 | * */
32 | fun setPosition(position: Int) {
33 | _position.value = position
34 | }
35 |
36 | /**
37 | * Set data
38 | * */
39 | fun setData(screenshot: ScreenShotModel) {
40 | _data.value = screenshot
41 | }
42 |
43 | /**
44 | * Set state
45 | * */
46 | fun setState(state: PreviewState) {
47 | _state.value = state
48 | }
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/screens/experience/ExperienceViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.screens.experience
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import androidx.paging.PagedList
7 | import androidx.paging.toLiveData
8 | import me.tumur.portfolio.repository.database.dao.experience.ExperienceDao
9 | import me.tumur.portfolio.repository.database.model.experience.ExperienceModel
10 | import me.tumur.portfolio.utils.constants.DbConstants
11 | import org.koin.core.KoinComponent
12 | import org.koin.core.inject
13 |
14 | class ExperienceViewModel : ViewModel(), KoinComponent {
15 |
16 | /** VARIABLES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
17 |
18 | /** Repository */
19 | private val experienceDao: ExperienceDao by inject()
20 |
21 | /** Selected item id */
22 | private val _selectedItem = MutableLiveData()
23 | val selectedItem: LiveData = _selectedItem
24 |
25 | /** Portfolio pager data */
26 | private val config = PagedList.Config.Builder()
27 | .setPageSize(10)
28 | .setEnablePlaceholders(true)
29 | .setInitialLoadSizeHint(5)
30 | .build()
31 |
32 | val data: LiveData> =
33 | experienceDao.getListItems(DbConstants.PERSON_ID).toLiveData(config)
34 |
35 | /** FUNCTIONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
36 |
37 | /**
38 | * Set selected item
39 | * */
40 | fun setSelectedItem(item: ExperienceModel?) {
41 | _selectedItem.value = item
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
34 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/adapters/listItemAdapters/experience/resource/ResourceAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.adapters.listItemAdapters.experience.resource
2 |
3 | import android.view.ViewGroup
4 | import androidx.paging.PagedListAdapter
5 | import androidx.recyclerview.widget.RecyclerView
6 | import me.tumur.portfolio.repository.database.model.resource.ResourceModel
7 | import me.tumur.portfolio.utils.adapters.listItemAdapters.portfolio.button.ButtonClickListener
8 |
9 | /**
10 | * An adapter that provides a list of [ResourceModel] to a [RecyclerView]
11 | * */
12 |
13 | class ResourceAdapter(private val clickListener: ButtonClickListener) :
14 | PagedListAdapter(
15 | ResourceDiffCallBack()
16 | ) {
17 |
18 | /**
19 | * Part of the RecyclerView adapter, called when RecyclerView needs a new [ResourceViewHolder]
20 | *
21 | * A [ResourceViewHolder] holds the view for the [RecyclerView] as well as providing information
22 | * to the RecyclerView such as where on the screen it was last drawn during scrolling.
23 | * */
24 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ResourceViewHolder {
25 | return ResourceViewHolder.from(parent)
26 | }
27 |
28 | /**
29 | * Part of the RecyclerView adapter, called when the RecyclerView needs to show an item.
30 | *
31 | * The [ResourceViewHolder] passed may be recycled so make sure that this sets any properties
32 | * that may be have been set previously
33 | * */
34 | override fun onBindViewHolder(holder: ResourceViewHolder, position: Int) {
35 | val resourceItem = getItem(position)
36 | holder.bind(resourceItem, clickListener)
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_portfolio.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/dao/favorite/FavoriteDao.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.dao.favorite
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.paging.DataSource
5 | import androidx.room.*
6 | import me.tumur.portfolio.repository.database.model.favorite.FavoriteModel
7 | import me.tumur.portfolio.utils.constants.DbConstants
8 |
9 | @Dao
10 | abstract class FavoriteDao {
11 |
12 | /** Update single item */
13 | @Transaction
14 | open suspend fun update(item: FavoriteModel): Long {
15 | deleteSingleItem(item.id)
16 | return insert(item)
17 | }
18 |
19 | /** Insert */
20 | @Insert(onConflict = OnConflictStrategy.REPLACE)
21 | abstract suspend fun insert(item: FavoriteModel): Long
22 |
23 | /** Delete */
24 | @Query(DbConstants.FAVORITE_DELETE)
25 | abstract suspend fun delete()
26 |
27 | /** Delete single item */
28 | @Query(DbConstants.FAVORITE_DELETE_SINGLE_ITEM)
29 | abstract suspend fun deleteSingleItem(id: String): Int
30 |
31 | /** Get single item */
32 | @Query(DbConstants.FAVORITE_GET_SINGLE_ITEM)
33 | abstract fun getSingleItem(id: String): LiveData
34 |
35 | /** Get paged list items */
36 | @Query(DbConstants.FAVORITE_GET_LIST_ITEMS)
37 | abstract fun getListItems(): DataSource.Factory
38 |
39 | /** Exist single item */
40 | @Query(DbConstants.FAVORITE_EXIST_SINGLE_ITEM)
41 | abstract fun existSingleItem(id: String): LiveData
42 |
43 | /** Get max order */
44 | @Query(DbConstants.FAVORITE_GET_MAX_ORDER)
45 | abstract suspend fun getMaxOrder(): FavoriteModel
46 |
47 | /** Check table */
48 | @Query(DbConstants.FAVORITE_CHECK)
49 | abstract fun check(): LiveData
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/favorite/FavoriteModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.favorite
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.Index
7 | import androidx.room.PrimaryKey
8 | import kotlinx.android.parcel.Parcelize
9 | import me.tumur.portfolio.utils.constants.DbConstants
10 | import java.util.*
11 |
12 | @Entity(tableName = DbConstants.FAVORITE, indices = [Index(value = [DbConstants.ID], unique = true)])
13 | @Parcelize
14 | data class FavoriteModel(
15 | @PrimaryKey(autoGenerate = false)
16 | @ColumnInfo(name = DbConstants.ID) var id: String,
17 | @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
18 | @ColumnInfo(name = DbConstants.TITLE) var title: String,
19 | @ColumnInfo(name = DbConstants.SUB_TITLE) var subTitle: String,
20 | @ColumnInfo(name = DbConstants.LOGO) var logo: String,
21 | @ColumnInfo(name = DbConstants.LOGO_DESCRIPTION) var logoDescription: String,
22 | @ColumnInfo(name = DbConstants.COVER_IMAGE) var coverImage: String,
23 | @ColumnInfo(name = DbConstants.IMAGE_DESCRIPTION) var imageDescription: String,
24 | @ColumnInfo(name = DbConstants.TEXT) var text: String,
25 | @ColumnInfo(name = DbConstants.INFO) var info: String,
26 | @ColumnInfo(name = DbConstants.DATE_FROM) var dateFrom: Date,
27 | @ColumnInfo(name = DbConstants.DATE_TO) var dateTo: Date,
28 | @ColumnInfo(name = DbConstants.HEADER) var header: String,
29 | @ColumnInfo(name = DbConstants.TYPE) var categoryType: Int,
30 | @ColumnInfo(name = DbConstants.VIDEO_URL) var videoUrl: String?,
31 | @ColumnInfo(name = DbConstants.ORDERS) var order: Int,
32 | @ColumnInfo(name = DbConstants.DATE) var date: Date
33 | ) : Parcelable
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_category_structure.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
24 |
30 |
36 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_app_info_update.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
34 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_screenshot.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
9 |
10 |
16 |
17 |
18 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/utils/fabButton/ScrollAwareFabButton.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.utils.fabButton
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import androidx.coordinatorlayout.widget.CoordinatorLayout
7 | import androidx.core.view.ViewCompat
8 | import com.google.android.material.floatingactionbutton.FloatingActionButton
9 |
10 |
11 | class ScrollAwareFABBehavior(context: Context, attrs: AttributeSet): FloatingActionButton.Behavior(context, attrs) {
12 |
13 | override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout,
14 | child: FloatingActionButton, directTargetChild: View, target: View,
15 | axes: Int, type: Int): Boolean {
16 | return axes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout,
17 | child, directTargetChild, target, axes, type)
18 | }
19 |
20 | override fun onNestedScroll(coordinatorLayout: CoordinatorLayout,
21 | child: FloatingActionButton, target: View, dxConsumed: Int, dyConsumed: Int,
22 | dxUnconsumed: Int, dyUnconsumed: Int, type: Int) {
23 | super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed,
24 | dyUnconsumed, type)
25 |
26 | if (dyConsumed > 0 && child.visibility == View.VISIBLE) {
27 | child.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
28 | override fun onHidden(fab: FloatingActionButton) {
29 | super.onHidden(fab)
30 | fab.visibility = View.INVISIBLE
31 | }
32 | })
33 | } else if (dyConsumed < 0 && child.visibility != View.VISIBLE) {
34 | child.show()
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_category_web.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
27 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_about_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/java/me/tumur/portfolio/repository/database/model/experience/ExperienceModel.kt:
--------------------------------------------------------------------------------
1 | package me.tumur.portfolio.repository.database.model.experience
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.Index
6 | import androidx.room.PrimaryKey
7 | import com.google.gson.annotations.SerializedName
8 | import me.tumur.portfolio.utils.constants.DbConstants
9 | import java.util.*
10 |
11 | @Entity(tableName = DbConstants.EXPERIENCE, indices = [Index(value = [DbConstants.ID], unique = true)])
12 | data class ExperienceModel(
13 | @PrimaryKey(autoGenerate = false)
14 | @SerializedName(DbConstants.ID) @ColumnInfo(name = DbConstants.ID) var id: String,
15 | @SerializedName(DbConstants.OWNER_ID) @ColumnInfo(name = DbConstants.OWNER_ID) var ownerId: String,
16 | @SerializedName(DbConstants.TITLE) @ColumnInfo(name = DbConstants.TITLE) var title: String,
17 | @SerializedName(DbConstants.COMPANY) @ColumnInfo(name = DbConstants.COMPANY) var company: String,
18 | @SerializedName(DbConstants.INFO) @ColumnInfo(name = DbConstants.INFO) var info: String,
19 | @SerializedName(DbConstants.DATE_FROM) @ColumnInfo(name = DbConstants.DATE_FROM) var dateFrom: Date,
20 | @SerializedName(DbConstants.DATE_TO) @ColumnInfo(name = DbConstants.DATE_TO) var dateTo: Date,
21 | @SerializedName(DbConstants.LOCATION) @ColumnInfo(name = DbConstants.LOCATION) var location: String,
22 | @SerializedName(DbConstants.LOGO) @ColumnInfo(name = DbConstants.LOGO) var logo: String,
23 | @SerializedName(DbConstants.LOGO_DESCRIPTION) @ColumnInfo(name = DbConstants.LOGO_DESCRIPTION) var logoDescription: String,
24 | @SerializedName(DbConstants.COVER_IMAGE) @ColumnInfo(name = DbConstants.COVER_IMAGE) var coverImage: String,
25 | @SerializedName(DbConstants.IMAGE_DESCRIPTION) @ColumnInfo(name = DbConstants.IMAGE_DESCRIPTION) var imageDescription: String,
26 | @SerializedName(DbConstants.ORDER) @ColumnInfo(name = DbConstants.ORDERS) var order: Int
27 | )
--------------------------------------------------------------------------------
/app/src/main/res/layout/preference_item_icon_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
24 |
25 |
26 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/portfolio_detail_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
20 |
21 | -
28 |
29 |
35 |
36 |
42 |
43 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------