├── .idea
├── .name
├── codeStyles
│ └── codeStyleConfig.xml
├── compiler.xml
├── vcs.xml
├── kotlinc.xml
├── dictionaries
│ └── ashutyagi.xml
├── misc.xml
├── runConfigurations.xml
├── gradle.xml
└── jarRepositories.xml
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── Lato.ttf
│ │ │ │ ├── Lato-Bold.ttf
│ │ │ │ ├── Lato-Black.ttf
│ │ │ │ ├── Lato-Light.ttf
│ │ │ │ └── Lato-Medium.ttf
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ ├── logo.png
│ │ │ │ ├── final_pallete.webp
│ │ │ │ ├── ic_wallpaper.webp
│ │ │ │ ├── bg_search.xml
│ │ │ │ ├── list_divider.xml
│ │ │ │ ├── bg_app_highlight.xml
│ │ │ │ ├── bg_popup_app_info.xml
│ │ │ │ ├── ripple_button.xml
│ │ │ │ ├── fast_scroll_handle.xml
│ │ │ │ ├── placeholder_big_image.xml
│ │ │ │ ├── rounded_corner_button.xml
│ │ │ │ ├── scroll_accent_drawable.xml
│ │ │ │ ├── cb_selector.xml
│ │ │ │ ├── ic_add_white.xml
│ │ │ │ ├── divider_app_list.xml
│ │ │ │ ├── ic_arrow_up_white.xml
│ │ │ │ ├── bg_bottom_sheet_dialog_fragment.xml
│ │ │ │ ├── ic_check_white.xml
│ │ │ │ ├── ic_back_white.xml
│ │ │ │ ├── ic_check_white_disabled.xml
│ │ │ │ ├── ic_close_white.xml
│ │ │ │ ├── ic_check_box_outline_white.xml
│ │ │ │ ├── ripple_cell.xml
│ │ │ │ ├── highlight.xml
│ │ │ │ ├── ic_search_white.xml
│ │ │ │ ├── state_pressed_ripple.xml
│ │ │ │ ├── shadow.xml
│ │ │ │ ├── ic_settings_white.xml
│ │ │ │ ├── ic_info.xml
│ │ │ │ ├── ic_checkbox_enabled.xml
│ │ │ │ ├── ic_edit.xml
│ │ │ │ ├── ic_refresh_white.xml
│ │ │ │ └── ic_delete.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── ic_launcher_round.png
│ │ │ │ ├── ic_launcher_settings.png
│ │ │ │ └── ic_launcher_settings_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── ic_launcher_round.png
│ │ │ │ ├── ic_launcher_settings.png
│ │ │ │ └── ic_launcher_settings_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── ic_launcher_round.png
│ │ │ │ ├── ic_launcher_settings.png
│ │ │ │ └── ic_launcher_settings_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── ic_launcher_round.png
│ │ │ │ ├── ic_launcher_settings.png
│ │ │ │ └── ic_launcher_settings_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── ic_launcher_round.png
│ │ │ │ ├── ic_launcher_settings.png
│ │ │ │ └── ic_launcher_settings_round.png
│ │ │ ├── anim
│ │ │ │ ├── no_anim.xml
│ │ │ │ ├── layout_animation_fall_down.xml
│ │ │ │ ├── grid_layout_animation_from_bottom.xml
│ │ │ │ ├── item_animation_from_bottom.xml
│ │ │ │ ├── item_animation_fall_down.xml
│ │ │ │ └── task_open_enter.xml
│ │ │ ├── values
│ │ │ │ ├── ic_launcher_settings_background.xml
│ │ │ │ ├── integers.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── attrs.xml
│ │ │ │ └── colors.xml
│ │ │ ├── interpolator
│ │ │ │ ├── decelerate_quart.xml
│ │ │ │ └── decelerate_quint.xml
│ │ │ ├── transition
│ │ │ │ └── change_image_transform.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── activity_screen_off.xml
│ │ │ │ ├── cell_wallpaper_pager.xml
│ │ │ │ ├── cell_wallpaper.xml
│ │ │ │ ├── activity_wallpaper_pager.xml
│ │ │ │ ├── activity_launcher.xml
│ │ │ │ ├── cell_recent_app_section.xml
│ │ │ │ ├── activity_launcher_settings.xml
│ │ │ │ ├── cell_default_color.xml
│ │ │ │ ├── cell_app_info_list.xml
│ │ │ │ ├── cell_app_info.xml
│ │ │ │ ├── activity_wallpaper_preview.xml
│ │ │ │ ├── cell_setting.xml
│ │ │ │ ├── activity_wallpaper_settings.xml
│ │ │ │ └── cell_app_selector.xml
│ │ │ ├── menu
│ │ │ │ └── wallpaper.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── sasuke
│ │ │ └── launcheroneplus
│ │ │ ├── data
│ │ │ ├── event
│ │ │ │ └── NoInternetEvent.kt
│ │ │ ├── model
│ │ │ │ ├── Status.kt
│ │ │ │ ├── Type.kt
│ │ │ │ ├── Ancestry.kt
│ │ │ │ ├── Category.kt
│ │ │ │ ├── Tag.kt
│ │ │ │ ├── CustomAppList.kt
│ │ │ │ ├── DefaultColor.kt
│ │ │ │ ├── DragData.kt
│ │ │ │ ├── ProfileImage.kt
│ │ │ │ ├── Wallpaper.kt
│ │ │ │ ├── Links.kt
│ │ │ │ ├── Urls.kt
│ │ │ │ ├── AppInfo.kt
│ │ │ │ ├── SettingPreference.kt
│ │ │ │ ├── Source.kt
│ │ │ │ ├── Error.kt
│ │ │ │ ├── App.kt
│ │ │ │ ├── CoverPhoto.kt
│ │ │ │ ├── Setting.kt
│ │ │ │ ├── Resource.kt
│ │ │ │ ├── User.kt
│ │ │ │ └── Result.kt
│ │ │ ├── exception
│ │ │ │ └── NoConnectivityException.kt
│ │ │ ├── db
│ │ │ │ ├── LauncherDB.kt
│ │ │ │ ├── RoomRepository.kt
│ │ │ │ └── dao
│ │ │ │ │ └── AppsDao.kt
│ │ │ └── network
│ │ │ │ ├── UnsplashService.kt
│ │ │ │ └── UnsplashRepository.kt
│ │ │ ├── di
│ │ │ ├── qualifiers
│ │ │ │ ├── CacheInterceptor.kt
│ │ │ │ ├── HeaderInterceptor.kt
│ │ │ │ ├── NetworkInterceptor.kt
│ │ │ │ ├── GridItemDecoration.kt
│ │ │ │ ├── HiddenAppLayoutManager.kt
│ │ │ │ ├── ListItemDecoration.kt
│ │ │ │ ├── LoggingInterceptor.kt
│ │ │ │ ├── StaleIfErrorInterceptor.kt
│ │ │ │ ├── VisibleAppLayoutManager.kt
│ │ │ │ └── ListDividerItemDecoration.kt
│ │ │ ├── scope
│ │ │ │ ├── LauncherAppScope.kt
│ │ │ │ ├── PerActivityScope.kt
│ │ │ │ └── PerFragmentScope.kt
│ │ │ ├── mapkey
│ │ │ │ └── ViewModelKey.kt
│ │ │ ├── module
│ │ │ │ ├── util
│ │ │ │ │ ├── ViewModelFactoryModule.kt
│ │ │ │ │ ├── SharedPreferenceModule.kt
│ │ │ │ │ └── UtilsModule.kt
│ │ │ │ ├── network
│ │ │ │ │ ├── UnsplashRepositoryModule.kt
│ │ │ │ │ └── UnsplashServiceModule.kt
│ │ │ │ ├── library
│ │ │ │ │ └── GlideModule.kt
│ │ │ │ ├── application
│ │ │ │ │ └── LauncherApplicationModule.kt
│ │ │ │ ├── activity
│ │ │ │ │ ├── AppDrawerActivityModule.kt
│ │ │ │ │ ├── LauncherSettingsActivityModule.kt
│ │ │ │ │ ├── WallpaperActivityModule.kt
│ │ │ │ │ ├── WallpaperPagerActivityModule.kt
│ │ │ │ │ ├── HiddenAppsActivityModule.kt
│ │ │ │ │ ├── ActivityBindingModule.kt
│ │ │ │ │ └── AppSelectionActivityModule.kt
│ │ │ │ ├── local
│ │ │ │ │ └── RoomRepositoryModule.kt
│ │ │ │ └── fragment
│ │ │ │ │ └── ColorPickerFragmentModule.kt
│ │ │ └── component
│ │ │ │ └── LauncherAppComponent.kt
│ │ │ ├── util
│ │ │ ├── GeneralUtils.kt
│ │ │ ├── OnCustomEventListeners.kt
│ │ │ ├── NetworkUtil.kt
│ │ │ ├── StorageUtils.kt
│ │ │ ├── SearchUtils.kt
│ │ │ ├── Constants.kt
│ │ │ ├── DaggerViewModelFactory.kt
│ │ │ ├── DebouncingEditTextQueryTextListener.kt
│ │ │ ├── DebouncingSearchViewQueryTextListener.kt
│ │ │ ├── BitmapUtils.kt
│ │ │ ├── ColorUtils.kt
│ │ │ ├── PackageResolverUtils.kt
│ │ │ ├── ApiCallback.kt
│ │ │ ├── KeyboardTriggerBehavior.kt
│ │ │ ├── SharedPreferencesSettingsLiveData.kt
│ │ │ ├── Extensions.kt
│ │ │ └── AppListUtil.kt
│ │ │ ├── ui
│ │ │ ├── widget
│ │ │ │ ├── recyclerview_fastscroll
│ │ │ │ │ ├── interfaces
│ │ │ │ │ │ └── OnFastScrollStateChangeListener.java
│ │ │ │ │ └── utils
│ │ │ │ │ │ └── Utils.java
│ │ │ │ └── GridRecyclerView.kt
│ │ │ ├── base
│ │ │ │ ├── MyItemKeyProvider.kt
│ │ │ │ ├── MyItemDetailsLookup.kt
│ │ │ │ ├── SpaceItemDecoration.kt
│ │ │ │ ├── RoundedBottomSheetDialogFragment.kt
│ │ │ │ ├── BaseViewHolder.kt
│ │ │ │ ├── GridSpacingItemDecoration.kt
│ │ │ │ └── MyDragShadowBuilder.kt
│ │ │ ├── hidden_apps
│ │ │ │ ├── HiddenAppsActivityViewModel.kt
│ │ │ │ └── app_selector
│ │ │ │ │ ├── VisibleAppSelectionViewHolder.kt
│ │ │ │ │ ├── HiddenAppSelectionViewHolder.kt
│ │ │ │ │ └── HiddenAppSelectionAdapter.kt
│ │ │ ├── screen_off
│ │ │ │ └── ScreenOffActivity.kt
│ │ │ ├── color_picker
│ │ │ │ ├── ColorPickerFragmentViewModel.kt
│ │ │ │ ├── ColorViewHolder.kt
│ │ │ │ └── ColorAdapter.kt
│ │ │ ├── settings
│ │ │ │ ├── LauncherSettingsActivityViewModel.kt
│ │ │ │ ├── LauncherSettingViewHolder.kt
│ │ │ │ ├── LauncherSettingAdapter.kt
│ │ │ │ ├── set_as_default
│ │ │ │ │ └── DefaultLauncherHandler.kt
│ │ │ │ └── app_drawer
│ │ │ │ │ └── AppDrawerActivityViewModel.kt
│ │ │ ├── drag_drop
│ │ │ │ ├── GridAppViewHolder.kt
│ │ │ │ └── GridViewAdapter.kt
│ │ │ ├── wallpaper
│ │ │ │ └── list
│ │ │ │ │ ├── grid
│ │ │ │ │ ├── WallpaperViewHolder.kt
│ │ │ │ │ ├── WallpaperAdapter.kt
│ │ │ │ │ └── WallpaperActivityViewModel.kt
│ │ │ │ │ └── pager
│ │ │ │ │ ├── WallpaperPagerViewHolder.kt
│ │ │ │ │ ├── WallpaperPagerAdapter.kt
│ │ │ │ │ └── WallpaperPagerActivityViewModel.kt
│ │ │ └── launcher
│ │ │ │ └── recent_apps
│ │ │ │ ├── RecentAppAdapter.kt
│ │ │ │ └── RecentAppSectionViewHolder.kt
│ │ │ └── receiver
│ │ │ └── AppChangeReceiver.kt
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── sasuke
│ │ │ └── launcheroneplus
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sasuke
│ │ └── launcheroneplus
│ │ └── ExampleInstrumentedTest.kt
└── google-services.json
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
└── gradlew.bat
/.idea/.name:
--------------------------------------------------------------------------------
1 | Launcher OnePlus
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name='Launcher OnePlus'
2 | include ':app'
3 |
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Lato.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/assets/fonts/Lato.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Lato-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/assets/fonts/Lato-Bold.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Lato-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/assets/fonts/Lato-Black.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Lato-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/assets/fonts/Lato-Light.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Lato-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/assets/fonts/Lato-Medium.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable/final_pallete.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/drawable/final_pallete.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_wallpaper.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/drawable/ic_wallpaper.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/event/NoInternetEvent.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.event
2 |
3 | class NoInternetEvent {
4 | }
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/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/AshuTyagi16/Launcher-OnePlus/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/AshuTyagi16/Launcher-OnePlus/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/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_settings_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_settings_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_settings_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_settings_round.png
--------------------------------------------------------------------------------
/app/src/main/res/anim/no_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_settings_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_settings_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_settings_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_settings_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_settings_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AshuTyagi16/Launcher-OnePlus/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_settings_round.png
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Status.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | enum class Status {
4 | SUCCESS,
5 | ERROR,
6 | LOADING
7 | }
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Type.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Type(
4 | val pretty_slug: String,
5 | val slug: String
6 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Ancestry.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Ancestry(
4 | val category: Category,
5 | val type: Type
6 | )
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_settings_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #569DCF
4 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Category.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Category(
4 | val pretty_slug: String,
5 | val slug: String
6 | )
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Tag.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Tag(
4 | val source: Source,
5 | val title: String,
6 | val type: String
7 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/CustomAppList.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class CustomAppList(
4 | val appList: List,
5 | var recentApp: List
6 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/DefaultColor.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class DefaultColor(
4 | val colorHex: Int,
5 | var isSelected: Boolean = false
6 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/DragData.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class DragData(
4 | val item: App,
5 | val width: Int,
6 | val height: Int
7 | )
--------------------------------------------------------------------------------
/app/src/main/res/interpolator/decelerate_quart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/interpolator/decelerate_quint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/.idea/dictionaries/ashutyagi.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | debouncing
5 | unsplash
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/ProfileImage.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class ProfileImage(
4 | val large: String,
5 | val medium: String,
6 | val small: String
7 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Wallpaper.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Wallpaper(
4 | val results: List,
5 | val total: Int,
6 | val total_pages: Int
7 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/CacheInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class CacheInterceptor {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/HeaderInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class HeaderInterceptor {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/NetworkInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class NetworkInterceptor {
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/GridItemDecoration.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class GridItemDecoration {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/HiddenAppLayoutManager.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class HiddenAppLayoutManager {
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/ListItemDecoration.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class ListItemDecoration {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/LoggingInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class LoggingInterceptor {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/StaleIfErrorInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class StaleIfErrorInterceptor {
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/VisibleAppLayoutManager.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class VisibleAppLayoutManager {
7 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/scope/LauncherAppScope.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.scope
2 |
3 | import javax.inject.Scope
4 |
5 | @Scope
6 | @Retention(AnnotationRetention.RUNTIME)
7 | annotation class LauncherAppScope {}
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/scope/PerActivityScope.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.scope
2 |
3 | import javax.inject.Scope
4 |
5 | @Scope
6 | @Retention(AnnotationRetention.RUNTIME)
7 | annotation class PerActivityScope {}
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/scope/PerFragmentScope.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.scope
2 |
3 | import javax.inject.Scope
4 |
5 | @Scope
6 | @Retention(AnnotationRetention.RUNTIME)
7 | annotation class PerFragmentScope {}
--------------------------------------------------------------------------------
/app/src/main/res/transition/change_image_transform.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/qualifiers/ListDividerItemDecoration.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.qualifiers
2 |
3 | import javax.inject.Qualifier
4 |
5 | @Qualifier
6 | annotation class ListDividerItemDecoration {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Links.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Links(
4 | val download: String,
5 | val download_location: String,
6 | val html: String,
7 | val self: String
8 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Urls.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Urls(
4 | val full: String,
5 | val raw: String,
6 | val regular: String,
7 | val small: String,
8 | val thumb: String
9 | )
--------------------------------------------------------------------------------
/app/src/main/res/drawable/list_divider.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/AppInfo.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | import android.graphics.drawable.Drawable
4 |
5 | data class AppInfo(
6 | val icon: Drawable,
7 | val packageName: String,
8 | val label: String
9 | )
--------------------------------------------------------------------------------
/app/src/main/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 200
4 | 300
5 | 400
6 |
7 |
--------------------------------------------------------------------------------
/.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/drawable/bg_app_highlight.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_popup_app_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ripple_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Nov 16 19:17:55 IST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/layout_animation_fall_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/fast_scroll_handle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/placeholder_big_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_corner_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/scroll_accent_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cb_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_white.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/divider_app_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/SettingPreference.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class SettingPreference(
4 | var primaryColor: Int,
5 | var isFastScrollEnabled: Boolean = true,
6 | var drawerStyle: DrawerStyle = DrawerStyle.VERTICAL,
7 | var backgroundColor: Int,
8 | var backgroundColorAlpha: Int
9 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Source.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Source(
4 | val ancestry: Ancestry,
5 | val cover_photo: CoverPhoto,
6 | val description: String,
7 | val meta_description: String,
8 | val meta_title: String,
9 | val subtitle: String,
10 | val title: String
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Error.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | import com.google.gson.annotations.SerializedName
4 |
5 | data class Error(
6 |
7 | @SerializedName("auth")
8 | val auth: Boolean = false,
9 | @SerializedName("message")
10 | val message: String = "Some Error Occurred"
11 | )
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_up_white.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/exception/NoConnectivityException.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.exception
2 |
3 | import com.sasuke.launcheroneplus.util.Constants
4 | import java.io.IOException
5 |
6 | class NoConnectivityException : IOException() {
7 |
8 | override val message: String?
9 | get() = Constants.INTERNET_NOT_CONNECTED
10 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_screen_off.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/mapkey/ViewModelKey.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.mapkey
2 |
3 | import androidx.lifecycle.ViewModel
4 | import dagger.MapKey
5 | import kotlin.reflect.KClass
6 |
7 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
8 | @MapKey
9 | annotation class ViewModelKey(val value: KClass)
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_bottom_sheet_dialog_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/grid_layout_animation_from_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/GeneralUtils.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.os.Build
4 |
5 | object GeneralUtils {
6 |
7 | val ATLEAST_MARSHMALLOW = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
8 |
9 | val ATLEAST_LOLLIPOP_MR1 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
10 |
11 | val ATLEAST_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
12 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_check_white.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_back_white.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_check_white_disabled.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/db/LauncherDB.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.db
2 |
3 | import androidx.room.Database
4 | import androidx.room.RoomDatabase
5 | import com.sasuke.launcheroneplus.data.db.dao.AppsDao
6 | import com.sasuke.launcheroneplus.data.model.App
7 |
8 | @Database(entities = [App::class], version = 1, exportSchema = false)
9 | abstract class LauncherDB : RoomDatabase() {
10 | abstract fun appsDao(): AppsDao
11 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/wallpaper.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_close_white.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/test/java/com/sasuke/launcheroneplus/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus
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/java/com/sasuke/launcheroneplus/di/module/util/ViewModelFactoryModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.util
2 |
3 | import androidx.lifecycle.ViewModelProvider
4 | import com.sasuke.launcheroneplus.util.DaggerViewModelFactory
5 | import dagger.Binds
6 | import dagger.Module
7 |
8 | @Module
9 | abstract class ViewModelFactoryModule {
10 | @Binds
11 | abstract fun bindViewModelFactory(viewModelFactory: DaggerViewModelFactory): ViewModelProvider.Factory
12 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_check_box_outline_white.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ripple_cell.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | -
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/OnCustomEventListeners.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.view.View
4 | import com.sasuke.launcheroneplus.data.model.App
5 |
6 | interface OnCustomEventListeners {
7 | fun onItemClick(position: Int, parent: View, appInfo: App)
8 | fun onItemLongClick(position: Int, parent: View, appInfo: App)
9 | fun onDragStart(position: Int, parent: View, appInfo: App)
10 | fun onEventCancel(position: Int, appInfo: App)
11 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/highlight.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 26sp
6 | 22sp
7 | 20sp
8 | 18sp
9 | 16sp
10 | 14sp
11 | 12sp
12 | 10sp
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search_white.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/item_animation_from_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/state_pressed_ripple.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | -
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/App.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | import android.os.Parcelable
4 | import androidx.room.ColumnInfo
5 | import androidx.room.Entity
6 | import androidx.room.PrimaryKey
7 | import kotlinx.android.parcel.Parcelize
8 |
9 | @Parcelize
10 | @Entity(tableName = "apps")
11 | data class App(
12 | @PrimaryKey(autoGenerate = true) val _id: Int = 0,
13 | val packageName: String,
14 | val label: String,
15 | var isSelected: Boolean = false,
16 | @ColumnInfo(name = "isHidden", index = true)
17 | var isHidden: Boolean = false
18 | ): Parcelable
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/widget/recyclerview_fastscroll/interfaces/OnFastScrollStateChangeListener.java:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.widget.recyclerview_fastscroll.interfaces;
2 |
3 | public interface OnFastScrollStateChangeListener {
4 |
5 | /**
6 | * Called when fast scrolling begins
7 | */
8 | void onFastScrollStart();
9 |
10 | /**
11 | * Called when fast scroller is being dragged
12 | */
13 | void onFastScrollDragged(String currentHeader);
14 |
15 | /**
16 | * Called when fast scrolling ends
17 | */
18 | void onFastScrollStop();
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/CoverPhoto.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class CoverPhoto(
4 | val alt_description: String,
5 | val categories: List,
6 | val color: String,
7 | val created_at: String,
8 | val current_user_collections: List,
9 | val description: String,
10 | val height: Int,
11 | val id: String,
12 | val liked_by_user: Boolean,
13 | val likes: Int,
14 | val links: Links,
15 | val promoted_at: String,
16 | val updated_at: String,
17 | val urls: Urls,
18 | val user: User,
19 | val width: Int
20 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Setting.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Setting(
4 | val icon: Int,
5 | val title: String,
6 | val description: String,
7 | val type: SettingsType,
8 | val shouldShow: Boolean = false
9 | )
10 |
11 | enum class SettingsType {
12 | HOME_SCREEN,
13 | APP_DRAWER,
14 | FOLDERS,
15 | LOOK_FEEL,
16 | NIGHT_MODE,
17 | GESTURE_INPUT,
18 | NOTIFICATION_BADGE,
19 | DEFAULT_LAUNCHER,
20 | SAY_THANKS,
21 | ABOUT,
22 | CONTACT_SUPPORT
23 | }
24 |
25 | enum class DrawerStyle {
26 | VERTICAL, LIST
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Resource.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Resource(val status: Status, val data: T?, val message: String?) {
4 | companion object {
5 | fun success(data: T?): Resource {
6 | return Resource(Status.SUCCESS, data, null)
7 | }
8 |
9 | fun error(error: Error = Error(), data: T? = null): Resource {
10 | return Resource(Status.ERROR, data, error.message)
11 | }
12 |
13 | fun loading(data: T? = null): Resource {
14 | return Resource(Status.LOADING, data, null)
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/User.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class User(
4 | val accepted_tos: Boolean,
5 | val bio: String,
6 | val first_name: String,
7 | val id: String,
8 | val instagram_username: String,
9 | val last_name: String,
10 | val links: Links,
11 | val location: String,
12 | val name: String,
13 | val portfolio_url: String,
14 | val profile_image: ProfileImage,
15 | val total_collections: Int,
16 | val total_likes: Int,
17 | val total_photos: Int,
18 | val twitter_username: String,
19 | val updated_at: String,
20 | val username: String
21 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/model/Result.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.model
2 |
3 | data class Result(
4 | val alt_description: String,
5 | val categories: List,
6 | val color: String,
7 | val created_at: String,
8 | val current_user_collections: List,
9 | val description: String,
10 | val height: Int,
11 | val id: String,
12 | val liked_by_user: Boolean,
13 | val likes: Int,
14 | val links: Links,
15 | val promoted_at: String,
16 | val sponsorship: Any,
17 | val tags: List,
18 | val updated_at: String,
19 | val urls: Urls,
20 | val user: User,
21 | val width: Int
22 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/network/UnsplashRepositoryModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.network
2 |
3 | import com.sasuke.launcheroneplus.data.network.UnsplashRepository
4 | import com.sasuke.launcheroneplus.data.network.UnsplashService
5 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
6 | import dagger.Module
7 | import dagger.Provides
8 |
9 | @Module(includes = [UnsplashServiceModule::class])
10 | class UnsplashRepositoryModule {
11 |
12 | @Provides
13 | @LauncherAppScope
14 | fun newsAppRepository(unsplashService: UnsplashService): UnsplashRepository {
15 | return UnsplashRepository(unsplashService)
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/MyItemKeyProvider.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import androidx.recyclerview.selection.ItemKeyProvider
4 | import androidx.recyclerview.widget.RecyclerView
5 |
6 | class MyItemKeyProvider(private val recyclerView: RecyclerView) :
7 | ItemKeyProvider(SCOPE_MAPPED) {
8 |
9 | override fun getKey(position: Int): Long? {
10 | return recyclerView.adapter?.getItemId(position)
11 | }
12 |
13 | override fun getPosition(key: Long): Int {
14 | val viewHolder = recyclerView.findViewHolderForItemId(key)
15 | return viewHolder?.layoutPosition ?: RecyclerView.NO_POSITION
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/NetworkUtil.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util;
2 |
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkInfo
6 |
7 | class NetworkUtil(val context: Context) {
8 |
9 | private val connectivityManager: ConnectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
10 | private var networkInfo: NetworkInfo? = connectivityManager.activeNetworkInfo
11 |
12 | fun isOnline(): Boolean {
13 | networkInfo = connectivityManager.activeNetworkInfo
14 | networkInfo?.let {
15 | return it.isConnected
16 | } ?: run { return false }
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/MyItemDetailsLookup.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import android.view.MotionEvent
4 | import androidx.recyclerview.selection.ItemDetailsLookup
5 | import androidx.recyclerview.widget.RecyclerView
6 |
7 | class MyItemDetailsLookup(private val recyclerView: RecyclerView) :
8 | ItemDetailsLookup() {
9 |
10 | override fun getItemDetails(event: MotionEvent): ItemDetails? {
11 | val view = recyclerView.findChildViewUnder(event.x, event.y)
12 | if (view != null) {
13 | // return (recyclerView.getChildViewHolder(view) as AppViewHolder)
14 | // .getItemDetails()
15 | }
16 | return null
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/library/GlideModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.library
2 |
3 | import android.content.Context
4 | import com.bumptech.glide.Glide
5 | import com.bumptech.glide.RequestManager
6 | import com.bumptech.glide.load.DecodeFormat
7 | import com.bumptech.glide.request.RequestOptions
8 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
9 | import dagger.Module
10 | import dagger.Provides
11 |
12 | @Module
13 | class GlideModule {
14 |
15 | @Provides
16 | @LauncherAppScope
17 | fun glide(context: Context): RequestManager {
18 | return Glide.with(context).setDefaultRequestOptions(
19 | RequestOptions().format(DecodeFormat.PREFER_RGB_565))
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/StorageUtils.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import androidx.annotation.WorkerThread
6 | import java.io.File
7 | import java.io.FileOutputStream
8 | import java.io.IOException
9 |
10 | class StorageUtils(private val context: Context) {
11 |
12 | @WorkerThread
13 | fun saveBitmapToFile(bitmap: Bitmap, label: String) {
14 | try {
15 | FileOutputStream(File(context.getIconFolderPath(label))).use { out ->
16 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
17 | }
18 | } catch (e: IOException) {
19 | e.printStackTrace()
20 | }
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 | -
12 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/SearchUtils.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import androidx.annotation.WorkerThread
4 |
5 | object SearchUtils {
6 |
7 | @WorkerThread
8 | suspend fun matches(
9 | haystack: String,
10 | needle: String
11 | ): Boolean {
12 | val queryLength = needle.length
13 | val titleLength = haystack.length
14 | if (titleLength < queryLength || queryLength <= 0) {
15 | return false
16 | }
17 | var ni = 0
18 | var hi = 0
19 | while (hi < titleLength) {
20 | if (haystack[hi] == needle[ni]) {
21 | ni++
22 | if (ni == queryLength) return true
23 | }
24 | hi++
25 | }
26 | return false
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/sasuke/launcheroneplus/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.sasuke.launcheroneplus", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/item_animation_fall_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/task_open_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/.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/res/layout/cell_wallpaper_pager.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/hidden_apps/HiddenAppsActivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.hidden_apps
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MediatorLiveData
5 | import androidx.lifecycle.ViewModel
6 | import com.sasuke.launcheroneplus.data.db.RoomRepository
7 | import com.sasuke.launcheroneplus.data.model.App
8 | import javax.inject.Inject
9 |
10 | class HiddenAppsActivityViewModel @Inject constructor(private val roomRepository: RoomRepository) :
11 | ViewModel() {
12 |
13 | private var _appList = MediatorLiveData>()
14 | val appList: LiveData>
15 | get() = _appList
16 |
17 | private lateinit var list: MutableList
18 |
19 | init {
20 | _appList.addSource(roomRepository.getOnlyHiddenApps()) {
21 | list = it
22 | _appList.postValue(it)
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings_white.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/Constants.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | object Constants {
4 |
5 | const val APP_LIST_SPAN_COUNT = 5
6 |
7 | val GRID_HORIZONTAL_SPACING = 5.dpToPx()
8 | val GRID_VERTICAL_SPACING = 20.dpToPx()
9 |
10 | val LIST_HORIZONTAL_SPACING = 5.dpToPx()
11 | val LIST_VERTICAL_SPACING = 10.dpToPx()
12 |
13 | const val EXTRA_API_VERSION_HEADER = "Accept-Version"
14 | const val EXTRA_API_VERSION = "v1"
15 |
16 | const val EXTRA_API_KEY = "S3wNzdfiMMhrwSDEJFIp-fPrzORJMXLBSyz_OIk5khE"
17 |
18 | const val PAGE_SIZE = 15
19 |
20 | const val ICON_FOLDER_NAME = "app_icon"
21 |
22 | const val RECENT_APPS = "RECENT_APPS"
23 |
24 | const val INTERNET_NOT_WORKING_MESSAGE = "Internet not working properly"
25 | const val INTERNET_NOT_CONNECTED = "Internet not connected"
26 |
27 | const val PREFERENCES = "SETTINGS_PREFERENCES"
28 | const val IS_PREFERENCES_SET = "IS_PREFERENCES_SET"
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/application/LauncherApplicationModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.application
2 |
3 | import com.sasuke.launcheroneplus.R
4 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
5 | import dagger.Module
6 | import dagger.Provides
7 | import io.github.inflationx.calligraphy3.CalligraphyConfig
8 | import io.github.inflationx.calligraphy3.CalligraphyInterceptor
9 | import timber.log.Timber
10 |
11 | @Module
12 | object LauncherApplicationModule {
13 |
14 | @Provides
15 | @LauncherAppScope
16 | fun timberTree(): Timber.Tree {
17 | return Timber.DebugTree()
18 | }
19 |
20 | @Provides
21 | @LauncherAppScope
22 | fun calligraphyInterceptor(): CalligraphyInterceptor {
23 | return CalligraphyInterceptor(
24 | CalligraphyConfig.Builder()
25 | .setDefaultFontPath("fonts/Lato.ttf")
26 | .setFontAttrId(R.attr.fontPath)
27 | .build()
28 | )
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_wallpaper.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/screen_off/ScreenOffActivity.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.screen_off
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import android.view.Window
7 | import android.view.WindowManager
8 | import com.sasuke.launcheroneplus.R
9 | import com.sasuke.launcheroneplus.ui.base.BaseActivity
10 |
11 | class ScreenOffActivity : BaseActivity() {
12 |
13 | companion object {
14 | fun newIntent(context: Context) = Intent(context, ScreenOffActivity::class.java)
15 | }
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | setTimeout()
19 | super.onCreate(savedInstanceState)
20 | setContentView(R.layout.activity_screen_off)
21 | }
22 |
23 | private fun setTimeout() {
24 | requestWindowFeature(Window.FEATURE_NO_TITLE)
25 | this.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)
26 | val params = window.attributes
27 | params.screenBrightness = 0f
28 | window.attributes = params
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/network/UnsplashService.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.network
2 |
3 | import com.sasuke.launcheroneplus.data.model.Result
4 | import com.sasuke.launcheroneplus.data.model.Wallpaper
5 | import com.sasuke.launcheroneplus.util.Constants
6 | import retrofit2.Call
7 | import retrofit2.http.GET
8 | import retrofit2.http.Query
9 |
10 | interface UnsplashService {
11 |
12 | @GET("search/photos")
13 | fun getWallpapersForQuery(
14 | @Query("query") query: String = "Switzerland",
15 | @Query("client_id") client_id: String = Constants.EXTRA_API_KEY,
16 | @Query("orientation") orientation: String = "portrait",
17 | @Query("page") pageNo: Int = 1,
18 | @Query("per_page") per_page: Int = Constants.PAGE_SIZE
19 | ): Call
20 |
21 | @GET("photos")
22 | fun getPopular(
23 | @Query("order_by") order_by: String = "popular",
24 | @Query("client_id") client_id: String = Constants.EXTRA_API_KEY,
25 | @Query("page") pageNo: Int = 1,
26 | @Query("per_page") per_page: Int = 50
27 | ): Call>
28 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_checkbox_enabled.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/AppDrawerActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import androidx.lifecycle.ViewModel
4 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
5 | import com.sasuke.launcheroneplus.di.module.fragment.ColorPickerFragmentModule
6 | import com.sasuke.launcheroneplus.di.scope.PerFragmentScope
7 | import com.sasuke.launcheroneplus.ui.color_picker.ColorPickerFragment
8 | import com.sasuke.launcheroneplus.ui.settings.app_drawer.AppDrawerActivityViewModel
9 | import dagger.Binds
10 | import dagger.Module
11 | import dagger.android.ContributesAndroidInjector
12 | import dagger.multibindings.IntoMap
13 |
14 | @Module
15 | abstract class AppDrawerActivityModule {
16 |
17 | @PerFragmentScope
18 | @ContributesAndroidInjector(modules = [ColorPickerFragmentModule::class])
19 | internal abstract fun colorPickerFragment(): ColorPickerFragment
20 |
21 | @Binds
22 | @IntoMap
23 | @ViewModelKey(AppDrawerActivityViewModel::class)
24 | abstract fun bindAppDrawerActivityViewModel(appDrawerActivityViewModel: AppDrawerActivityViewModel): ViewModel
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/local/RoomRepositoryModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.local
2 |
3 | import android.content.Context
4 | import androidx.room.Room
5 | import com.sasuke.launcheroneplus.data.db.dao.AppsDao
6 | import com.sasuke.launcheroneplus.data.db.LauncherDB
7 | import com.sasuke.launcheroneplus.data.db.RoomRepository
8 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
9 | import dagger.Module
10 | import dagger.Provides
11 |
12 | @Module
13 | class RoomRepositoryModule {
14 |
15 | @Provides
16 | @LauncherAppScope
17 | fun launcherDB(context: Context): LauncherDB {
18 | return Room.databaseBuilder(
19 | context,
20 | LauncherDB::class.java, "launcher_db"
21 | ).fallbackToDestructiveMigration().build()
22 | }
23 |
24 | @Provides
25 | @LauncherAppScope
26 | fun appDao(launcherDB: LauncherDB): AppsDao {
27 | return launcherDB.appsDao()
28 | }
29 |
30 | @Provides
31 | @LauncherAppScope
32 | fun roomRepository(appsDao: AppsDao): RoomRepository {
33 | return RoomRepository(appsDao)
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_wallpaper_pager.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
23 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/DaggerViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import javax.inject.Inject
6 | import javax.inject.Provider
7 |
8 | @Suppress("UNCHECKED_CAST")
9 | class DaggerViewModelFactory @Inject constructor(
10 | private val creators: Map, @JvmSuppressWildcards Provider>
11 | ) : ViewModelProvider.Factory {
12 | @Suppress("UNCHECKED_CAST")
13 | override fun create(modelClass: Class): T {
14 | var creator: Provider? = creators[modelClass]
15 | if (creator == null) {
16 | for ((key, value) in creators) {
17 | if (modelClass.isAssignableFrom(key)) {
18 | creator = value
19 | break
20 | }
21 | }
22 | }
23 | if (creator == null) {
24 | throw IllegalArgumentException("Unknown model class: $modelClass")
25 | }
26 | try {
27 | return creator.get() as T
28 | } catch (e: Exception) {
29 | throw RuntimeException(e)
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/SpaceItemDecoration.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import android.graphics.Rect
4 | import android.view.View
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.sasuke.launcheroneplus.util.Constants
7 |
8 | class SpaceItemDecoration(private val horizontalSpace: Int, private val verticalSpace: Int) :
9 | RecyclerView.ItemDecoration() {
10 |
11 | companion object {
12 | private const val EDGE_SPACING_FACTOR = 1
13 | }
14 |
15 | override fun getItemOffsets(
16 | outRect: Rect,
17 | view: View,
18 | parent: RecyclerView,
19 | state: RecyclerView.State
20 | ) {
21 | outRect.left = horizontalSpace
22 | outRect.right = horizontalSpace
23 |
24 | if (parent.getChildLayoutPosition(view) == state.itemCount - 1)
25 | outRect.bottom = EDGE_SPACING_FACTOR * verticalSpace
26 | else
27 | outRect.bottom = verticalSpace
28 |
29 | if (parent.getChildLayoutPosition(view) >= 0 && parent.getChildLayoutPosition(view) < Constants.APP_LIST_SPAN_COUNT)
30 | outRect.top = EDGE_SPACING_FACTOR * verticalSpace
31 | else
32 | outRect.top = verticalSpace
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_recent_app_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/util/SharedPreferenceModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.util
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 | import androidx.preference.PreferenceManager
6 | import com.google.gson.Gson
7 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
8 | import com.sasuke.launcheroneplus.util.SharedPreferenceUtil
9 | import com.sasuke.launcheroneplus.util.SharedPreferencesSettingsLiveData
10 | import dagger.Module
11 | import dagger.Provides
12 |
13 | @Module
14 | object SharedPreferenceModule {
15 |
16 | @Provides
17 | @LauncherAppScope
18 | fun sharedPreferenceUtil(preferences: SharedPreferences, gson: Gson): SharedPreferenceUtil {
19 | return SharedPreferenceUtil(preferences, gson)
20 | }
21 |
22 | @Provides
23 | @LauncherAppScope
24 | fun preferences(context: Context): SharedPreferences {
25 | return PreferenceManager.getDefaultSharedPreferences(context)
26 | }
27 |
28 | @Provides
29 | @LauncherAppScope
30 | fun getSharedPreferencesUserLiveData(
31 | preferences: SharedPreferences,
32 | gson: Gson
33 | ): SharedPreferencesSettingsLiveData {
34 | return SharedPreferencesSettingsLiveData(preferences, gson)
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/color_picker/ColorPickerFragmentViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.color_picker
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import androidx.lifecycle.viewModelScope
7 | import com.google.gson.Gson
8 | import com.sasuke.launcheroneplus.data.model.DefaultColor
9 | import com.sasuke.launcheroneplus.util.ColorUtils
10 | import com.sasuke.launcheroneplus.util.Constants
11 | import com.sasuke.launcheroneplus.util.SharedPreferenceUtil
12 | import kotlinx.coroutines.Dispatchers
13 | import kotlinx.coroutines.launch
14 | import kotlinx.coroutines.withContext
15 | import javax.inject.Inject
16 |
17 | class ColorPickerFragmentViewModel @Inject constructor(
18 | private val colorUtils: ColorUtils
19 | ) :
20 | ViewModel() {
21 |
22 | private val _defaultColorsLiveData = MutableLiveData>()
23 | val defaultColorsLiveData: LiveData>
24 | get() = _defaultColorsLiveData
25 |
26 | fun getDefaultColorList() {
27 | viewModelScope.launch {
28 | withContext(Dispatchers.IO) {
29 | _defaultColorsLiveData.postValue(colorUtils.getDefaultColorHexList())
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/settings/LauncherSettingsActivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.settings
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import androidx.lifecycle.viewModelScope
7 | import com.sasuke.launcheroneplus.data.model.Resource
8 | import com.sasuke.launcheroneplus.data.model.Setting
9 | import com.sasuke.launcheroneplus.util.SettingUtils
10 | import kotlinx.coroutines.Dispatchers
11 | import kotlinx.coroutines.launch
12 | import kotlinx.coroutines.withContext
13 | import javax.inject.Inject
14 |
15 | class LauncherSettingsActivityViewModel @Inject constructor(private val settingUtils: SettingUtils) :
16 | ViewModel() {
17 |
18 | private val _settingsLiveData = MutableLiveData>>()
19 | val settingsLiveData: LiveData>>
20 | get() = _settingsLiveData
21 |
22 | fun getSettings() {
23 | _settingsLiveData.postValue(Resource.loading())
24 | viewModelScope.launch {
25 | withContext(Dispatchers.IO) {
26 | val settings = settingUtils.getSettings().filter {
27 | it.shouldShow
28 | }
29 | _settingsLiveData.postValue(Resource.success(settings))
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/RoundedBottomSheetDialogFragment.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.os.Bundle
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.annotation.LayoutRes
10 | import com.google.android.material.bottomsheet.BottomSheetDialog
11 | import com.google.android.material.bottomsheet.BottomSheetDialogFragment
12 | import com.sasuke.launcheroneplus.R
13 | import dagger.android.support.AndroidSupportInjection
14 |
15 | abstract class RoundedBottomSheetDialogFragment : BottomSheetDialogFragment() {
16 |
17 | override fun onAttach(context: Context) {
18 | AndroidSupportInjection.inject(this)
19 | super.onAttach(context)
20 | }
21 |
22 | override fun getTheme(): Int = R.style.BottomSheetDialogTheme
23 |
24 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
25 | BottomSheetDialog(requireContext(), theme)
26 |
27 | @LayoutRes
28 | abstract fun getLayoutResId(): Int
29 |
30 | override fun onCreateView(
31 | inflater: LayoutInflater,
32 | container: ViewGroup?,
33 | savedInstanceState: Bundle?
34 | ): View? {
35 | return inflater.inflate(getLayoutResId(), container, false)
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/network/UnsplashServiceModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.network
2 |
3 | import com.google.gson.Gson
4 | import com.google.gson.GsonBuilder
5 | import com.sasuke.launcheroneplus.data.network.UnsplashService
6 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
7 | import dagger.Module
8 | import dagger.Provides
9 | import okhttp3.OkHttpClient
10 | import retrofit2.Retrofit
11 | import retrofit2.converter.gson.GsonConverterFactory
12 |
13 | @Module(includes = [NetworkModule::class])
14 | class UnsplashServiceModule {
15 |
16 | companion object {
17 | private const val BASE_URL = "https://api.unsplash.com/"
18 | }
19 |
20 | @Provides
21 | @LauncherAppScope
22 | fun newsAppService(retrofit: Retrofit): UnsplashService {
23 | return retrofit.create(UnsplashService::class.java)
24 | }
25 |
26 | @Provides
27 | @LauncherAppScope
28 | fun retrofit(okHttpClient: OkHttpClient, gson: Gson): Retrofit {
29 | return Retrofit.Builder()
30 | .addConverterFactory(GsonConverterFactory.create(gson))
31 | .client(okHttpClient)
32 | .baseUrl(BASE_URL)
33 | .build()
34 | }
35 |
36 | @Provides
37 | @LauncherAppScope
38 | fun gson(): Gson {
39 | return GsonBuilder().create()
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_launcher_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_edit.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/LauncherSettingsActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.ViewModel
5 | import androidx.recyclerview.widget.LinearLayoutManager
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
8 | import com.sasuke.launcheroneplus.di.scope.PerActivityScope
9 | import com.sasuke.launcheroneplus.ui.settings.LauncherSettingAdapter
10 | import com.sasuke.launcheroneplus.ui.settings.LauncherSettingsActivityViewModel
11 | import dagger.Binds
12 | import dagger.Module
13 | import dagger.Provides
14 | import dagger.multibindings.IntoMap
15 |
16 | @Module
17 | abstract class LauncherSettingsActivityModule {
18 |
19 | companion object {
20 |
21 | @Provides
22 | @PerActivityScope
23 | fun adapter(glide: RequestManager): LauncherSettingAdapter {
24 | return LauncherSettingAdapter(glide)
25 | }
26 |
27 | @Provides
28 | @PerActivityScope
29 | fun layoutManager(context: Context): LinearLayoutManager {
30 | return LinearLayoutManager(context)
31 | }
32 | }
33 |
34 | @Binds
35 | @IntoMap
36 | @ViewModelKey(LauncherSettingsActivityViewModel::class)
37 | abstract fun bindLauncherSettingsActivityViewModel(launcherSettingsActivityViewModel: LauncherSettingsActivityViewModel): ViewModel
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/db/RoomRepository.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.db
2 |
3 | import android.database.DatabaseUtils
4 | import android.util.Log
5 | import androidx.annotation.WorkerThread
6 | import androidx.lifecycle.LiveData
7 | import com.sasuke.launcheroneplus.data.db.dao.AppsDao
8 | import com.sasuke.launcheroneplus.data.model.App
9 |
10 | class RoomRepository(private val appsDao: AppsDao) {
11 |
12 | fun getApps(includeHidden: Boolean = false): LiveData> {
13 | if (includeHidden)
14 | return appsDao.getAllApps()
15 | else
16 | return appsDao.getVisibleApps(false)
17 | }
18 |
19 | fun getOnlyHiddenApps(): LiveData> {
20 | return appsDao.getOnlyHiddenApps(true)
21 | }
22 |
23 | fun isAppsInDB(): Int {
24 | return appsDao.isAppsInDB()
25 | }
26 |
27 | @WorkerThread
28 | suspend fun deleteAllApps() {
29 | return appsDao.deleteAllApps()
30 | }
31 |
32 | @WorkerThread
33 | suspend fun deleteApp(packageName: String) {
34 | return appsDao.deleteApp(packageName)
35 | }
36 |
37 | @WorkerThread
38 | suspend fun insert(app: App) {
39 | appsDao.insert(app)
40 | }
41 |
42 | @WorkerThread
43 | suspend fun hideApps(ids: IntArray) {
44 | appsDao.hideApps(ids, true)
45 | }
46 |
47 | @WorkerThread
48 | suspend fun unhideApps(ids: IntArray) {
49 | appsDao.unhideApps(ids, false)
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/db/dao/AppsDao.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.db.dao
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.Dao
5 | import androidx.room.Insert
6 | import androidx.room.OnConflictStrategy
7 | import androidx.room.Query
8 | import com.sasuke.launcheroneplus.data.model.App
9 |
10 | @Dao
11 | interface AppsDao {
12 |
13 | @Query("SELECT * from apps WHERE isHidden =:isHidden ORDER BY label COLLATE NOCASE ASC")
14 | fun getVisibleApps(isHidden: Boolean): LiveData>
15 |
16 | @Query("SELECT * from apps ORDER BY label COLLATE NOCASE ASC")
17 | fun getAllApps(): LiveData>
18 |
19 | @Query("SELECT * from apps WHERE isHidden =:isHidden ORDER BY label COLLATE NOCASE ASC")
20 | fun getOnlyHiddenApps(isHidden: Boolean): LiveData>
21 |
22 | @Query("SELECT COUNT(*) from apps")
23 | fun isAppsInDB(): Int
24 |
25 | @Insert(onConflict = OnConflictStrategy.REPLACE)
26 | suspend fun insert(app: App)
27 |
28 | @Query("UPDATE apps SET isHidden = :isHidden where _id IN(:ids)")
29 | suspend fun hideApps(ids: IntArray, isHidden: Boolean)
30 |
31 | @Query("UPDATE apps SET isHidden = :isHidden where _id IN(:ids)")
32 | suspend fun unhideApps(ids: IntArray, isHidden: Boolean)
33 |
34 | @Query("DELETE FROM apps")
35 | suspend fun deleteAllApps()
36 |
37 | @Query("DELETE FROM apps where packageName = :packageName")
38 | suspend fun deleteApp(packageName: String)
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/drag_drop/GridAppViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.drag_drop
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.bumptech.glide.RequestManager
6 | import com.sasuke.launcheroneplus.data.model.App
7 | import com.sasuke.launcheroneplus.util.Constants
8 | import com.sasuke.launcheroneplus.util.getIconFolderPath
9 | import kotlinx.android.synthetic.main.cell_app_info.view.*
10 | import java.io.File
11 |
12 | class GridAppViewHolder(
13 | itemView: View,
14 | private val glide: RequestManager
15 | ) :
16 | RecyclerView.ViewHolder(itemView) {
17 |
18 | private lateinit var onClickListeners: OnClickListeners
19 |
20 | fun setAppInfo(appInfo: App) {
21 | glide.load(File(itemView.context.getIconFolderPath(appInfo.label)))
22 | .into(itemView.ivAppIcon)
23 | itemView.tvAppLabel.text = appInfo.label
24 |
25 | itemView.setOnClickListener {
26 | if (::onClickListeners.isInitialized)
27 | onClickListeners.onItemClick(adapterPosition, itemView, appInfo)
28 | }
29 |
30 | itemView.setOnLongClickListener {
31 | return@setOnLongClickListener false
32 | }
33 | }
34 |
35 | interface OnClickListeners {
36 | fun onItemClick(position: Int, parent: View, appInfo: App)
37 | }
38 |
39 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
40 | this.onClickListeners = onClickListeners
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/hidden_apps/app_selector/VisibleAppSelectionViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.hidden_apps.app_selector
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.bumptech.glide.RequestManager
6 | import com.sasuke.launcheroneplus.data.model.App
7 | import com.sasuke.launcheroneplus.util.Constants
8 | import com.sasuke.launcheroneplus.util.getIconFolderPath
9 | import kotlinx.android.synthetic.main.cell_app_selector.view.*
10 | import java.io.File
11 |
12 | class VisibleAppSelectionViewHolder(itemView: View, private val glide: RequestManager) :
13 | RecyclerView.ViewHolder(itemView) {
14 |
15 | private lateinit var onClickListeners: OnClickListeners
16 |
17 | fun setApp(appInfo: App) {
18 | glide.load(File(itemView.context.getIconFolderPath(appInfo.label)))
19 | .into(itemView.ivAppIcon)
20 | itemView.tvAppLabel.text = appInfo.label
21 |
22 | itemView.setOnClickListener {
23 | if (::onClickListeners.isInitialized)
24 | onClickListeners.onVisibleItemClick(adapterPosition, appInfo)
25 | }
26 | }
27 |
28 | fun toggle(checked: Boolean) {
29 | itemView.checkbox.isChecked = checked
30 | }
31 |
32 | interface OnClickListeners {
33 | fun onVisibleItemClick(position: Int, appInfo: App)
34 | }
35 |
36 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
37 | this.onClickListeners = onClickListeners
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_default_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/DebouncingEditTextQueryTextListener.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.text.Editable
4 | import android.text.TextWatcher
5 | import androidx.lifecycle.Lifecycle
6 | import androidx.lifecycle.LifecycleObserver
7 | import androidx.lifecycle.OnLifecycleEvent
8 | import kotlinx.coroutines.*
9 |
10 | class DebouncingEditTextQueryTextListener(
11 | lifecycle: Lifecycle,
12 | private val onDebouncingQueryTextChange: (CharSequence?) -> Unit
13 | ) : TextWatcher, LifecycleObserver {
14 |
15 | private var debouncePeriod: Long = 100
16 |
17 | private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
18 |
19 | private var searchJob: Job? = null
20 |
21 | init {
22 | lifecycle.addObserver(this)
23 | }
24 |
25 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
26 | private fun destroy() {
27 | searchJob?.cancel()
28 | }
29 |
30 | override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
31 |
32 | }
33 |
34 | override fun onTextChanged(newText: CharSequence?, p1: Int, p2: Int, p3: Int) {
35 | searchJob?.cancel()
36 | searchJob = coroutineScope.launch {
37 | newText?.let {
38 | delay(debouncePeriod)
39 | withContext(Dispatchers.Main) {
40 | onDebouncingQueryTextChange(it.toString())
41 | }
42 | }
43 | }
44 | }
45 |
46 | override fun afterTextChanged(p0: Editable?) {
47 |
48 | }
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/DebouncingSearchViewQueryTextListener.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import androidx.lifecycle.Lifecycle
4 | import androidx.lifecycle.LifecycleObserver
5 | import androidx.lifecycle.OnLifecycleEvent
6 | import com.miguelcatalan.materialsearchview.MaterialSearchView
7 | import kotlinx.coroutines.*
8 |
9 | class DebouncingSearchViewQueryTextListener(
10 | lifecycle: Lifecycle,
11 | private val onDebouncingQueryTextChange: (String?) -> Unit
12 | ) : MaterialSearchView.OnQueryTextListener, LifecycleObserver {
13 |
14 | private var debouncePeriod: Long = 700
15 |
16 | private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
17 |
18 | private var searchJob: Job? = null
19 |
20 | init {
21 | lifecycle.addObserver(this)
22 | }
23 |
24 | override fun onQueryTextSubmit(query: String?): Boolean {
25 | query?.let {
26 | onDebouncingQueryTextChange(it)
27 | return false
28 | } ?: run {
29 | return false
30 | }
31 | }
32 |
33 | override fun onQueryTextChange(newText: String?): Boolean {
34 | searchJob?.cancel()
35 | searchJob = coroutineScope.launch {
36 | newText?.let {
37 | delay(debouncePeriod)
38 | onDebouncingQueryTextChange(newText)
39 | }
40 | }
41 | return false
42 | }
43 |
44 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
45 | private fun destroy() {
46 | searchJob?.cancel()
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/fragment/ColorPickerFragmentModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.fragment
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.ViewModel
5 | import androidx.recyclerview.widget.GridLayoutManager
6 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
7 | import com.sasuke.launcheroneplus.di.scope.PerFragmentScope
8 | import com.sasuke.launcheroneplus.ui.base.SpaceItemDecoration
9 | import com.sasuke.launcheroneplus.ui.color_picker.ColorAdapter
10 | import com.sasuke.launcheroneplus.ui.color_picker.ColorPickerFragmentViewModel
11 | import dagger.Binds
12 | import dagger.Module
13 | import dagger.Provides
14 | import dagger.multibindings.IntoMap
15 |
16 | @Module
17 | abstract class ColorPickerFragmentModule {
18 |
19 | companion object {
20 |
21 | @Provides
22 | @PerFragmentScope
23 | fun adapter(): ColorAdapter {
24 | return ColorAdapter()
25 | }
26 |
27 | @Provides
28 | @PerFragmentScope
29 | fun layoutManager(context: Context): GridLayoutManager {
30 | return GridLayoutManager(context, 4)
31 | }
32 |
33 | @Provides
34 | @PerFragmentScope
35 | fun itemDecoration(): SpaceItemDecoration {
36 | return SpaceItemDecoration(50, 30)
37 | }
38 | }
39 |
40 | @Binds
41 | @IntoMap
42 | @ViewModelKey(ColorPickerFragmentViewModel::class)
43 | abstract fun bindColorPickerFragmentViewModel(colorPickerFragmentViewModel: ColorPickerFragmentViewModel): ViewModel
44 | }
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "756468755900",
4 | "firebase_url": "https://launcheroneplus.firebaseio.com",
5 | "project_id": "launcheroneplus",
6 | "storage_bucket": "launcheroneplus.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:756468755900:android:6178da189526f9ba6ccfb9",
12 | "android_client_info": {
13 | "package_name": "com.sasuke.launcheroneplus"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "756468755900-mgj0ofvb17pduactdahj177l22mtqab5.apps.googleusercontent.com",
19 | "client_type": 1,
20 | "android_info": {
21 | "package_name": "com.sasuke.launcheroneplus",
22 | "certificate_hash": "9cfe111655147f35bf664b3f76f892d77cf26473"
23 | }
24 | },
25 | {
26 | "client_id": "756468755900-fhr0gbeqpr8r5voju06tsn8m8d6pd7hu.apps.googleusercontent.com",
27 | "client_type": 3
28 | }
29 | ],
30 | "api_key": [
31 | {
32 | "current_key": "AIzaSyAIRBkQ9EETrQSxmDSKRs265WutFApBPHc"
33 | }
34 | ],
35 | "services": {
36 | "appinvite_service": {
37 | "other_platform_oauth_client": [
38 | {
39 | "client_id": "756468755900-fhr0gbeqpr8r5voju06tsn8m8d6pd7hu.apps.googleusercontent.com",
40 | "client_type": 3
41 | }
42 | ]
43 | }
44 | }
45 | }
46 | ],
47 | "configuration_version": "1"
48 | }
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/hidden_apps/app_selector/HiddenAppSelectionViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.hidden_apps.app_selector
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.bumptech.glide.RequestManager
6 | import com.sasuke.launcheroneplus.data.model.App
7 | import com.sasuke.launcheroneplus.util.Constants
8 | import com.sasuke.launcheroneplus.util.getIconFolderPath
9 | import kotlinx.android.synthetic.main.cell_app_selector.view.*
10 | import java.io.File
11 |
12 | class HiddenAppSelectionViewHolder(itemView: View, private val glide: RequestManager) :
13 | RecyclerView.ViewHolder(itemView) {
14 |
15 | private lateinit var onClickListeners: OnClickListeners
16 |
17 | fun setApp(appInfo: App) {
18 | glide.load(File(itemView.context.getIconFolderPath(appInfo.label)))
19 | .into(itemView.ivAppIcon)
20 | itemView.tvAppLabel.text = appInfo.label
21 |
22 | itemView.setOnClickListener {
23 | if (::onClickListeners.isInitialized)
24 | onClickListeners.onHiddenItemClick(adapterPosition, appInfo)
25 | }
26 |
27 | if (appInfo.isHidden)
28 | itemView.checkbox.isChecked = true
29 | }
30 |
31 | fun toggle(checked: Boolean) {
32 | itemView.checkbox.isChecked = checked
33 | }
34 |
35 | interface OnClickListeners {
36 | fun onHiddenItemClick(position: Int, appInfo: App)
37 | }
38 |
39 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
40 | this.onClickListeners = onClickListeners
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_refresh_white.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_app_info_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/BitmapUtils.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.graphics.Bitmap
4 | import android.graphics.BitmapFactory
5 | import android.graphics.Canvas
6 | import android.graphics.drawable.BitmapDrawable
7 | import android.graphics.drawable.Drawable
8 | import androidx.annotation.WorkerThread
9 |
10 | class BitmapUtils {
11 |
12 | @WorkerThread
13 | fun drawableToBitmap(drawable: Drawable): Bitmap? {
14 | var bitmap: Bitmap? = null
15 | if (drawable is BitmapDrawable) {
16 | if (drawable.bitmap != null) {
17 | return drawable.bitmap
18 | }
19 | }
20 | bitmap = if (drawable.intrinsicWidth <= 0 || drawable.intrinsicHeight <= 0) {
21 | Bitmap.createBitmap(
22 | 1,
23 | 1,
24 | Bitmap.Config.ARGB_8888
25 | ) // Single color bitmap will be created of 1x1 pixel
26 | } else {
27 | Bitmap.createBitmap(
28 | drawable.intrinsicWidth/2,
29 | drawable.intrinsicHeight/2,
30 | Bitmap.Config.ARGB_8888
31 | )
32 | }
33 | val canvas = Canvas(bitmap)
34 | drawable.setBounds(0, 0, canvas.width, canvas.height)
35 | drawable.draw(canvas)
36 | return bitmap
37 | }
38 |
39 | @WorkerThread
40 | suspend fun getBitmapFromPath(path: String): Bitmap? {
41 | val options = BitmapFactory.Options()
42 | options.inPreferredConfig = Bitmap.Config.ARGB_8888
43 | return BitmapFactory.decodeFile(path, options)
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/util/UtilsModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.util
2 |
3 | import android.content.Context
4 | import com.sasuke.launcheroneplus.data.db.RoomRepository
5 | import com.sasuke.launcheroneplus.di.module.local.RoomRepositoryModule
6 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
7 | import com.sasuke.launcheroneplus.util.*
8 | import dagger.Module
9 | import dagger.Provides
10 |
11 | @Module(includes = [RoomRepositoryModule::class])
12 | class UtilsModule {
13 |
14 | @Provides
15 | @LauncherAppScope
16 | fun storageUtils(context: Context): StorageUtils {
17 | return StorageUtils(context)
18 | }
19 |
20 | @Provides
21 | @LauncherAppScope
22 | fun bitmapUtils(): BitmapUtils {
23 | return BitmapUtils()
24 | }
25 |
26 | @Provides
27 | @LauncherAppScope()
28 | fun appListUtils(
29 | roomRepository: RoomRepository,
30 | bitmapUtils: BitmapUtils,
31 | storageUtils: StorageUtils,
32 | context: Context
33 | ): AppListUtil {
34 | return AppListUtil(roomRepository, bitmapUtils, storageUtils, context.packageManager, context)
35 | }
36 |
37 | @Provides
38 | @LauncherAppScope
39 | fun networkUtil(context: Context): NetworkUtil {
40 | return NetworkUtil(context)
41 | }
42 |
43 | @Provides
44 | @LauncherAppScope
45 | fun settingUtils(context: Context): SettingUtils {
46 | return SettingUtils(context)
47 | }
48 |
49 | @Provides
50 | @LauncherAppScope
51 | fun colorUtils(context: Context): ColorUtils {
52 | return ColorUtils(context)
53 | }
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/BaseViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import android.view.View
4 | import androidx.dynamicanimation.animation.SpringAnimation
5 | import androidx.dynamicanimation.animation.SpringForce
6 | import androidx.recyclerview.widget.RecyclerView
7 |
8 | open class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
9 | var currentVelocity = 0f
10 |
11 | /**
12 | * A [SpringAnimation] for this RecyclerView item. This animation rotates the view with a bouncy
13 | * spring configuration, resulting in the oscillation effect.
14 | *
15 | * The animation is started in [Recyclerview.onScrollListener].
16 | */
17 | val rotation: SpringAnimation = SpringAnimation(itemView, SpringAnimation.ROTATION)
18 | .setSpring(
19 | SpringForce()
20 | .setFinalPosition(0f)
21 | .setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY)
22 | .setStiffness(SpringForce.STIFFNESS_LOW)
23 | )
24 | .addUpdateListener { _, _, velocity ->
25 | currentVelocity = velocity
26 | }
27 |
28 | /**
29 | * A [SpringAnimation] for this RecyclerView item. This animation is used to bring the item back
30 | * after the over-scroll effect.
31 | */
32 | val translationY: SpringAnimation = SpringAnimation(itemView, SpringAnimation.TRANSLATION_Y)
33 | .setSpring(
34 | SpringForce()
35 | .setFinalPosition(0f)
36 | .setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY)
37 | .setStiffness(SpringForce.STIFFNESS_LOW)
38 | )
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/color_picker/ColorViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.color_picker
2 |
3 | import android.view.View
4 | import androidx.appcompat.content.res.AppCompatResources
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.sasuke.launcheroneplus.R
7 | import com.sasuke.launcheroneplus.data.model.DefaultColor
8 | import com.sasuke.launcheroneplus.util.hide
9 | import com.sasuke.launcheroneplus.util.show
10 | import com.sasuke.launcheroneplus.util.updateTint
11 | import kotlinx.android.synthetic.main.cell_default_color.view.*
12 |
13 | class ColorViewHolder(itemView: View) :
14 | RecyclerView.ViewHolder(itemView) {
15 |
16 | private lateinit var onClickListeners: OnClickListeners
17 |
18 | fun setColor(color: DefaultColor) {
19 | AppCompatResources.getDrawable(itemView.context, R.drawable.scroll_accent_drawable)
20 | ?.let { drawable ->
21 | drawable.updateTint(color.colorHex)
22 | itemView.ivColor.background = drawable
23 | }
24 |
25 | itemView.setOnClickListener {
26 | if (::onClickListeners.isInitialized)
27 | onClickListeners.onItemClick(adapterPosition, color.colorHex)
28 | }
29 | }
30 |
31 | fun toggle(flag: Boolean) {
32 | if (flag)
33 | itemView.ivSelected.show()
34 | else
35 | itemView.ivSelected.hide()
36 | }
37 |
38 | interface OnClickListeners {
39 | fun onItemClick(position: Int, color: Int)
40 | }
41 |
42 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
43 | this.onClickListeners = onClickListeners
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/GridSpacingItemDecoration.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import android.graphics.Rect
4 | import android.view.View
5 | import androidx.recyclerview.widget.RecyclerView
6 | import androidx.recyclerview.widget.RecyclerView.ItemDecoration
7 |
8 | class GridSpacingItemDecoration(
9 | private val spanCount: Int,
10 | private val spacing: Int,
11 | private val includeEdge: Boolean
12 | ) : ItemDecoration() {
13 | override fun getItemOffsets(
14 | outRect: Rect,
15 | view: View,
16 | parent: RecyclerView,
17 | state: RecyclerView.State
18 | ) {
19 | val position = parent.getChildAdapterPosition(view) // item position
20 | val column = position % spanCount // item column
21 | if (includeEdge) {
22 | outRect.left =
23 | spacing - column * spacing / spanCount // spacing - column * ((1f / spanCount) * spacing)
24 | outRect.right =
25 | (column + 1) * spacing / spanCount // (column + 1) * ((1f / spanCount) * spacing)
26 | if (position < spanCount) { // top edge
27 | outRect.top = spacing
28 | }
29 | outRect.bottom = spacing // item bottom
30 | } else {
31 | outRect.left = column * spacing / spanCount // column * ((1f / spanCount) * spacing)
32 | outRect.right =
33 | spacing - (column + 1) * spacing / spanCount // spacing - (column + 1) * ((1f / spanCount) * spacing)
34 | if (position >= spanCount) {
35 | outRect.top = spacing // item top
36 | }
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/WallpaperActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.ViewModel
5 | import androidx.recyclerview.widget.GridLayoutManager
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
8 | import com.sasuke.launcheroneplus.di.scope.PerActivityScope
9 | import com.sasuke.launcheroneplus.ui.base.SpaceItemDecoration
10 | import com.sasuke.launcheroneplus.ui.wallpaper.list.grid.WallpaperActivityViewModel
11 | import com.sasuke.launcheroneplus.ui.wallpaper.list.grid.WallpaperAdapter
12 | import dagger.Binds
13 | import dagger.Module
14 | import dagger.Provides
15 | import dagger.multibindings.IntoMap
16 |
17 | @Module
18 | abstract class WallpaperActivityModule {
19 |
20 | companion object {
21 |
22 | @Provides
23 | @PerActivityScope
24 | fun adapter(glide: RequestManager): WallpaperAdapter {
25 | return WallpaperAdapter(
26 | glide
27 | )
28 | }
29 |
30 | @Provides
31 | @PerActivityScope
32 | fun layoutManager(context: Context): GridLayoutManager {
33 | return GridLayoutManager(context, 3)
34 | }
35 |
36 | @Provides
37 | @PerActivityScope
38 | fun itemDecoration(): SpaceItemDecoration {
39 | return SpaceItemDecoration(10, 20)
40 | }
41 | }
42 |
43 | @Binds
44 | @IntoMap
45 | @ViewModelKey(WallpaperActivityViewModel::class)
46 | abstract fun bindWallpaperActivityViewModel(wallpaperActivityViewModel: WallpaperActivityViewModel): ViewModel
47 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_app_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/ColorUtils.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.content.Context
4 | import androidx.annotation.WorkerThread
5 | import androidx.core.content.ContextCompat
6 | import com.sasuke.launcheroneplus.R
7 | import com.sasuke.launcheroneplus.data.model.DefaultColor
8 |
9 | class ColorUtils(private val context: Context) {
10 |
11 | @WorkerThread
12 | suspend fun getDefaultColorHexList(): MutableList {
13 | val list = ArrayList()
14 |
15 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_one)))
16 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_two)))
17 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_three)))
18 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_four)))
19 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_five)))
20 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_six)))
21 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_seven)))
22 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_eight)))
23 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_nine)))
24 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_ten)))
25 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_eleven)))
26 | list.add(DefaultColor(ContextCompat.getColor(context, R.color.default_search_bar_twelve)))
27 | return list
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/wallpaper/list/grid/WallpaperViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.wallpaper.list.grid
2 |
3 | import android.view.View
4 | import android.widget.ImageView
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.bumptech.glide.RequestManager
7 | import com.bumptech.glide.load.resource.bitmap.CenterCrop
8 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners
9 | import com.bumptech.glide.request.RequestOptions
10 | import com.sasuke.launcheroneplus.R
11 | import com.sasuke.launcheroneplus.data.model.Result
12 | import com.sasuke.launcheroneplus.util.dpToPx
13 | import kotlinx.android.synthetic.main.cell_wallpaper.view.*
14 |
15 | class WallpaperViewHolder(itemView: View, private val glide: RequestManager) :
16 | RecyclerView.ViewHolder(itemView) {
17 |
18 | private lateinit var onItemClickListener: OnItemClickListener
19 | private var requestOptions = RequestOptions()
20 |
21 | init {
22 | requestOptions = requestOptions.transform(CenterCrop(), RoundedCorners(8.dpToPx()))
23 | }
24 |
25 | fun setWallpaper(result: Result) {
26 | glide.load(result.urls.small)
27 | .placeholder(R.drawable.placeholder_big_image)
28 | .apply(requestOptions)
29 | .into(itemView.ivWallpaper)
30 |
31 | itemView.setOnClickListener {
32 | if (::onItemClickListener.isInitialized)
33 | onItemClickListener.onItemClick(adapterPosition, itemView.ivWallpaper)
34 | }
35 | }
36 |
37 | interface OnItemClickListener {
38 | fun onItemClick(position: Int, imageView: ImageView)
39 | }
40 |
41 | fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
42 | this.onItemClickListener = onItemClickListener
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/wallpaper/list/pager/WallpaperPagerViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.wallpaper.list.pager
2 |
3 | import android.view.View
4 | import android.widget.ImageView
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.bumptech.glide.RequestManager
7 | import com.bumptech.glide.load.resource.bitmap.CenterCrop
8 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners
9 | import com.bumptech.glide.request.RequestOptions
10 | import com.sasuke.launcheroneplus.R
11 | import com.sasuke.launcheroneplus.data.model.Result
12 | import com.sasuke.launcheroneplus.util.dpToPx
13 | import kotlinx.android.synthetic.main.cell_wallpaper_pager.view.*
14 |
15 | class WallpaperPagerViewHolder(itemView: View, private val glide: RequestManager) :
16 | RecyclerView.ViewHolder(itemView) {
17 |
18 | private var requestOptions = RequestOptions()
19 |
20 | init {
21 | requestOptions = requestOptions.transform(CenterCrop(), RoundedCorners(8.dpToPx()))
22 | }
23 |
24 | private lateinit var onItemListener: OnItemListener
25 |
26 | fun setWallpaper(result: Result) {
27 | glide
28 | .load(result.urls.regular)
29 | .placeholder(R.drawable.placeholder_big_image)
30 | .apply(requestOptions)
31 | .dontAnimate()
32 | .into(itemView.ivWallpaper)
33 |
34 | itemView.setOnClickListener {
35 | if (::onItemListener.isInitialized)
36 | onItemListener.onItemClick(adapterPosition, result, itemView.ivWallpaper)
37 | }
38 | }
39 |
40 | interface OnItemListener {
41 | fun onItemClick(position: Int, result: Result, imageView: ImageView)
42 | }
43 |
44 | fun setOnItemListener(onItemListener: OnItemListener) {
45 | this.onItemListener = onItemListener
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/settings/LauncherSettingViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.settings
2 |
3 | import android.view.View
4 | import androidx.appcompat.content.res.AppCompatResources
5 | import androidx.core.graphics.drawable.DrawableCompat
6 | import androidx.recyclerview.widget.RecyclerView
7 | import com.bumptech.glide.RequestManager
8 | import com.sasuke.launcheroneplus.LauncherApp
9 | import com.sasuke.launcheroneplus.data.model.Setting
10 | import com.sasuke.launcheroneplus.util.updateTint
11 | import kotlinx.android.synthetic.main.cell_setting.view.*
12 |
13 | class LauncherSettingViewHolder(itemView: View, private val glide: RequestManager) :
14 | RecyclerView.ViewHolder(itemView) {
15 |
16 | private lateinit var onItemClickListener: OnItemClickListener
17 |
18 | fun setSettingInfo(setting: Setting) {
19 | if (LauncherApp.color != 0) {
20 | AppCompatResources.getDrawable(itemView.context, setting.icon)?.let {
21 | it.updateTint(LauncherApp.color)
22 | glide
23 | .load(it)
24 | .into(itemView.ivIcon)
25 | }
26 | } else {
27 | glide
28 | .load(setting.icon)
29 | .into(itemView.ivIcon)
30 | }
31 | itemView.tvSettingTitle.text = setting.title
32 | itemView.tvSettingDescription.text = setting.description
33 |
34 | itemView.setOnClickListener {
35 | if (::onItemClickListener.isInitialized)
36 | onItemClickListener.onItemClick(setting)
37 | }
38 | }
39 |
40 | interface OnItemClickListener {
41 | fun onItemClick(setting: Setting)
42 | }
43 |
44 | fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
45 | this.onItemClickListener = onItemClickListener
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/widget/recyclerview_fastscroll/utils/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Tim Malseed
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sasuke.launcheroneplus.ui.widget.recyclerview_fastscroll.utils;
18 |
19 | import android.annotation.TargetApi;
20 | import android.content.res.Resources;
21 | import android.os.Build;
22 | import android.util.TypedValue;
23 | import android.view.View;
24 |
25 | public class Utils {
26 |
27 | /**
28 | * Converts dp to px
29 | *
30 | * @param res Resources
31 | * @param dp the value in dp
32 | * @return int
33 | */
34 | public static int toPixels(Resources res, float dp) {
35 | return (int) (dp * res.getDisplayMetrics().density);
36 | }
37 |
38 | /**
39 | * Converts sp to px
40 | *
41 | * @param res Resources
42 | * @param sp the value in sp
43 | * @return int
44 | */
45 | public static int toScreenPixels(Resources res, float sp) {
46 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, res.getDisplayMetrics());
47 | }
48 |
49 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
50 | public static boolean isRtl(Resources res) {
51 | return res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/base/MyDragShadowBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.base
2 |
3 | import android.graphics.Canvas
4 | import android.graphics.Point
5 | import android.view.View
6 | import android.widget.ImageView
7 |
8 | class MyDragShadowBuilder(v: View) : View.DragShadowBuilder(v) {
9 |
10 | private var drawable = (v as ImageView).drawable
11 |
12 | init {
13 | drawable = drawable.constantState?.newDrawable()?.mutate()
14 | }
15 |
16 | private val shadow = drawable
17 |
18 | // Defines a callback that sends the drag shadow dimensions and touch point back to the
19 | // system.
20 | override fun onProvideShadowMetrics(size: Point, touch: Point) {
21 | // Sets the width of the shadow to half the width of the original View
22 | val width: Int = (view.width)
23 |
24 | // Sets the height of the shadow to half the height of the original View
25 | val height: Int = (view.height)
26 |
27 | // The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the
28 | // Canvas that the system will provide. As a result, the drag shadow will fill the
29 | // Canvas.
30 | shadow.setBounds(0, 0, width, height)
31 |
32 | // Sets the size parameter's width and height values. These get back to the system
33 | // through the size parameter.
34 | size.set(width, height)
35 |
36 | // Sets the touch point's position to be in the middle of the drag shadow
37 | touch.set((width / 2), (height * 1.5).toInt())
38 | }
39 |
40 | // Defines a callback that draws the drag shadow in a Canvas that the system constructs
41 | // from the dimensions passed in onProvideShadowMetrics().
42 | override fun onDrawShadow(canvas: Canvas) {
43 | // Draws the ColorDrawable in the Canvas passed in from the system.
44 | shadow.draw(canvas)
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/data/network/UnsplashRepository.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.data.network
2 |
3 | import com.sasuke.launcheroneplus.data.model.Error
4 | import com.sasuke.launcheroneplus.data.model.Result
5 | import com.sasuke.launcheroneplus.data.model.Wallpaper
6 | import com.sasuke.launcheroneplus.util.ApiCallback
7 |
8 | class UnsplashRepository(private val unsplashService: UnsplashService) {
9 |
10 | fun getWallpapers(
11 | query: String = "Switzerland",
12 | page: Int = 1,
13 | onGetWallpaperListener: OnGetWallpaperListener
14 | ) {
15 | unsplashService.getWallpapersForQuery(query = query, pageNo = page)
16 | .enqueue(object : ApiCallback() {
17 | override fun success(response: Wallpaper) {
18 | onGetWallpaperListener.onGetWallpaperSuccess(response)
19 | }
20 |
21 | override fun failure(error: Error) {
22 | onGetWallpaperListener.onGetWallpaperFailure(error)
23 | }
24 |
25 | })
26 | }
27 |
28 | fun getPopular(onGetPopularListener: OnGetPopularListener) {
29 | unsplashService.getPopular().enqueue(object : ApiCallback>() {
30 | override fun success(response: List) {
31 | onGetPopularListener.onGetPopularSuccess(response)
32 | }
33 |
34 | override fun failure(error: Error) {
35 | onGetPopularListener.onGetPopularFailure(error)
36 | }
37 |
38 | })
39 | }
40 |
41 | interface OnGetWallpaperListener {
42 | fun onGetWallpaperSuccess(wallpaper: Wallpaper)
43 |
44 | fun onGetWallpaperFailure(error: Error)
45 | }
46 |
47 | interface OnGetPopularListener {
48 | fun onGetPopularSuccess(list: List)
49 |
50 | fun onGetPopularFailure(error: Error)
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/PackageResolverUtils.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.content.Intent
4 | import android.content.pm.PackageManager
5 | import androidx.annotation.WorkerThread
6 | import com.sasuke.launcheroneplus.data.model.AppInfo
7 | import kotlin.collections.ArrayList
8 |
9 | object PackageResolverUtils {
10 |
11 | @WorkerThread
12 | fun getSortedAppList(
13 | packageManager: PackageManager
14 | ): MutableList {
15 |
16 | val mainIntent = Intent(Intent.ACTION_MAIN, null)
17 | mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)
18 |
19 | val list = packageManager.queryIntentActivities(mainIntent, 0)
20 | val appInoList: MutableList = ArrayList(list.size)
21 |
22 | list.forEach { resolveInfo ->
23 | val packageInfo = AppInfo(
24 | icon = resolveInfo.loadIcon(packageManager),
25 | packageName = resolveInfo.activityInfo.packageName,
26 | label = resolveInfo.loadLabel(packageManager).toString()
27 | )
28 | appInoList.add(packageInfo)
29 | }
30 |
31 | appInoList.sortBy {
32 | it.label.toLowerCased()
33 | }
34 |
35 | return appInoList
36 | }
37 |
38 | @WorkerThread
39 | fun getAppInfoFromPackageName(packageManager: PackageManager, packageName: String): AppInfo? {
40 | val intent = Intent()
41 | intent.`package` = packageName
42 | intent.addCategory(Intent.CATEGORY_LAUNCHER)
43 | var appInfo: AppInfo? = null
44 | packageManager.resolveActivity(intent, 0)?.let {
45 | appInfo = AppInfo(
46 | icon = it.loadIcon(packageManager),
47 | packageName = it.activityInfo.packageName,
48 | label = it.loadLabel(packageManager).toString()
49 | )
50 | }
51 | return appInfo
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/settings/LauncherSettingAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.settings
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.R
8 | import com.sasuke.launcheroneplus.data.model.Setting
9 |
10 | class LauncherSettingAdapter(private val glide: RequestManager) :
11 | RecyclerView.Adapter(),
12 | LauncherSettingViewHolder.OnItemClickListener {
13 |
14 | private lateinit var settings: List
15 | private lateinit var onItemClickListener: OnItemClickListener
16 |
17 |
18 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LauncherSettingViewHolder {
19 | val view = LayoutInflater.from(parent.context).inflate(R.layout.cell_setting, parent, false)
20 | return LauncherSettingViewHolder(view, glide)
21 | }
22 |
23 | override fun getItemCount(): Int {
24 | return if (::settings.isInitialized) settings.size else 0
25 | }
26 |
27 | override fun onBindViewHolder(holder: LauncherSettingViewHolder, position: Int) {
28 | if (::settings.isInitialized) {
29 | holder.setSettingInfo(settings[position])
30 | holder.setOnItemClickListener(this)
31 | }
32 | }
33 |
34 | fun setSettings(list: List) {
35 | this.settings = list
36 | notifyDataSetChanged()
37 | }
38 |
39 | override fun onItemClick(setting: Setting) {
40 | if (::onItemClickListener.isInitialized)
41 | onItemClickListener.onItemClick(setting)
42 | }
43 |
44 | interface OnItemClickListener {
45 | fun onItemClick(setting: Setting)
46 | }
47 |
48 | fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
49 | this.onItemClickListener = onItemClickListener
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | @color/search_bar
6 |
7 |
8 | #ff000000
9 | #cc000000
10 | #383838
11 | #212121
12 | #191919
13 | #ffffffff
14 | #46FFFFFF
15 | #66ffffff
16 | #00ffffff
17 |
18 |
19 | @color/black
20 | #80000000
21 | #66ffffff
22 |
23 |
24 | #ff0080ff
25 | #FF6E40
26 | #4d0080ff
27 | #00ffffff
28 |
29 |
30 |
31 | #303960
32 | #2fc4b2
33 | #00adb5
34 | #f08a5d
35 | #b83b5e
36 | #95e1d3
37 | @color/black_transparent
38 | #3f72af
39 | #e84545
40 | #a2d5f2
41 | #769fcd
42 | #ea9a96
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/widget/GridRecyclerView.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.widget
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.view.animation.GridLayoutAnimationController
8 | import androidx.recyclerview.widget.GridLayoutManager
9 | import androidx.recyclerview.widget.RecyclerView
10 |
11 | class GridRecyclerView : RecyclerView {
12 |
13 | constructor(context: Context) : super(context)
14 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
15 | constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
16 | context,
17 | attrs,
18 | defStyle
19 | )
20 |
21 | override fun attachLayoutAnimationParameters(
22 | child: View,
23 | params: ViewGroup.LayoutParams,
24 | index: Int,
25 | count: Int
26 | ) {
27 | val adapter = adapter
28 | val layoutManager = layoutManager
29 | if (adapter != null && layoutManager is GridLayoutManager) {
30 | val animationParams = params.layoutAnimationParameters
31 | as? GridLayoutAnimationController.AnimationParameters
32 | ?: GridLayoutAnimationController.AnimationParameters()
33 | params.layoutAnimationParameters = animationParams
34 |
35 | val columns = layoutManager.spanCount
36 | animationParams.count = count
37 | animationParams.index = index
38 | animationParams.columnsCount = columns
39 | animationParams.rowsCount = count / columns
40 |
41 | val invertedIndex = count - 1 - index
42 | animationParams.column = columns - 1 - (invertedIndex % columns)
43 | animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns
44 | } else {
45 | super.attachLayoutAnimationParameters(child, params, index, count)
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delete.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/wallpaper/list/grid/WallpaperAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.wallpaper.list.grid
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import android.widget.ImageView
6 | import androidx.recyclerview.widget.RecyclerView
7 | import com.bumptech.glide.RequestManager
8 | import com.sasuke.launcheroneplus.R
9 | import com.sasuke.launcheroneplus.data.model.Result
10 |
11 | class WallpaperAdapter(private val glide: RequestManager) :
12 | RecyclerView.Adapter(), WallpaperViewHolder.OnItemClickListener {
13 |
14 | val wallpapers = ArrayList()
15 | private lateinit var onItemClickListener: OnItemClickListener
16 |
17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WallpaperViewHolder {
18 | val view =
19 | LayoutInflater.from(parent.context).inflate(R.layout.cell_wallpaper, parent, false)
20 | val holder = WallpaperViewHolder(
21 | view,
22 | glide
23 | )
24 | holder.setOnItemClickListener(this)
25 | return holder
26 | }
27 |
28 | override fun getItemCount(): Int {
29 | return wallpapers.size
30 | }
31 |
32 | override fun onBindViewHolder(holder: WallpaperViewHolder, position: Int) {
33 | if (wallpapers.isNotEmpty() && position < wallpapers.size) {
34 | holder.setWallpaper(wallpapers[position])
35 | }
36 | }
37 |
38 | fun addWallpapers(list: List) {
39 | wallpapers.addAll(list)
40 | }
41 |
42 | override fun onItemClick(position: Int, imageView: ImageView) {
43 | if (::onItemClickListener.isInitialized)
44 | onItemClickListener.onItemClick(position, imageView)
45 | }
46 |
47 | interface OnItemClickListener {
48 | fun onItemClick(position: Int, imageView: ImageView)
49 | }
50 |
51 | fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
52 | this.onItemClickListener = onItemClickListener
53 | }
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/ApiCallback.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import com.google.gson.Gson
4 | import retrofit2.Call
5 | import retrofit2.Response
6 | import timber.log.Timber
7 | import com.sasuke.launcheroneplus.data.exception.NoConnectivityException
8 | import com.sasuke.launcheroneplus.data.model.Error
9 | import java.net.UnknownHostException
10 | import javax.net.ssl.SSLHandshakeException
11 |
12 | abstract class ApiCallback : retrofit2.Callback {
13 |
14 | final override fun onResponse(call: Call, response: Response) {
15 | if (response.isSuccessful) {
16 | response.body()?.let { body ->
17 | success(body)
18 | } ?: run {
19 | createError(response)
20 | }
21 | } else {
22 | createError(response)
23 | }
24 | }
25 |
26 | final override fun onFailure(call: Call, t: Throwable) {
27 | Timber.e(t.cause)
28 | var error = Error()
29 | if (t is NoConnectivityException) {
30 | error = Error(true, t.message!!)
31 | failure(error)
32 | } else if (t is SSLHandshakeException) {
33 | error = Error(true, Constants.INTERNET_NOT_WORKING_MESSAGE)
34 | failure(error)
35 | } else if (t is UnknownHostException) {
36 | error = Error(true, Constants.INTERNET_NOT_WORKING_MESSAGE)
37 | failure(error)
38 | } else
39 | failure(error)
40 | }
41 |
42 | private fun createError(response: Response) {
43 | response.errorBody()?.let { errorBody ->
44 | try {
45 | val error = Gson().fromJson(errorBody.string(), Error::class.java)
46 | failure(error)
47 | } catch (e: Exception) {
48 | failure(Error(true, e.localizedMessage))
49 | }
50 | } ?: run { failure(Error()) }
51 | }
52 |
53 | abstract fun success(response: T)
54 |
55 | abstract fun failure(error: Error)
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/WallpaperPagerActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.ViewModel
5 | import androidx.recyclerview.widget.LinearLayoutManager
6 | import androidx.recyclerview.widget.PagerSnapHelper
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.bumptech.glide.RequestManager
9 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
10 | import com.sasuke.launcheroneplus.di.scope.PerActivityScope
11 | import com.sasuke.launcheroneplus.ui.base.SpaceItemDecoration
12 | import com.sasuke.launcheroneplus.ui.wallpaper.list.pager.WallpaperPagerActivityViewModel
13 | import com.sasuke.launcheroneplus.ui.wallpaper.list.pager.WallpaperPagerAdapter
14 | import dagger.Binds
15 | import dagger.Module
16 | import dagger.Provides
17 | import dagger.multibindings.IntoMap
18 |
19 | @Module
20 | abstract class WallpaperPagerActivityModule {
21 |
22 | companion object {
23 |
24 | @Provides
25 | @PerActivityScope
26 | fun adapter(glide: RequestManager): WallpaperPagerAdapter {
27 | return WallpaperPagerAdapter(
28 | glide
29 | )
30 | }
31 |
32 | @Provides
33 | @PerActivityScope
34 | fun layoutManager(context: Context): LinearLayoutManager {
35 | return LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
36 | }
37 |
38 | @Provides
39 | @PerActivityScope
40 | fun itemDecoration(): SpaceItemDecoration {
41 | return SpaceItemDecoration(30, 250)
42 | }
43 |
44 | @Provides
45 | @PerActivityScope
46 | fun pagerSnapHelper(): PagerSnapHelper {
47 | return PagerSnapHelper()
48 | }
49 | }
50 |
51 | @Binds
52 | @IntoMap
53 | @ViewModelKey(WallpaperPagerActivityViewModel::class)
54 | abstract fun bindWallpaperPagerActivityViewModel(wallpaperPagerActivityViewModel: WallpaperPagerActivityViewModel): ViewModel
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/settings/set_as_default/DefaultLauncherHandler.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.settings.set_as_default
2 |
3 | import android.annotation.TargetApi
4 | import android.app.Activity
5 | import android.app.role.RoleManager
6 | import android.content.Intent
7 | import android.content.pm.PackageManager
8 | import android.os.Build
9 | import android.provider.Settings
10 | import com.sasuke.launcheroneplus.BuildConfig
11 | import com.sasuke.launcheroneplus.util.GeneralUtils
12 |
13 | abstract class DefaultLauncherHandler(protected val activity: Activity) {
14 |
15 | companion object {
16 | fun create(activity: Activity): DefaultLauncherHandler {
17 | if (GeneralUtils.ATLEAST_Q) {
18 | return DefaultHomeCompatVQ(activity)
19 | }
20 | return DefaultHomeCompatVNMr1(activity)
21 | }
22 | }
23 |
24 | abstract fun isDefaultHome(): Boolean
25 |
26 | fun requestDefaultHome() {
27 | activity.startActivity(Intent(Settings.ACTION_HOME_SETTINGS))
28 | }
29 |
30 | class DefaultHomeCompatVNMr1(activity: Activity) : DefaultLauncherHandler(activity) {
31 |
32 | override fun isDefaultHome(): Boolean {
33 | return BuildConfig.APPLICATION_ID == resolveDefaultHome()
34 | }
35 |
36 | private fun resolveDefaultHome(): String? {
37 | val homeIntent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
38 | val info = activity.packageManager
39 | .resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY)
40 | return info?.activityInfo?.packageName
41 | }
42 | }
43 |
44 | @TargetApi(Build.VERSION_CODES.Q)
45 | class DefaultHomeCompatVQ(activity: Activity) : DefaultLauncherHandler(activity) {
46 |
47 | private val roleManager = activity.getSystemService(RoleManager::class.java)!!
48 |
49 | override fun isDefaultHome(): Boolean {
50 | return roleManager.isRoleHeld(RoleManager.ROLE_HOME)
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/HiddenAppsActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.ViewModel
5 | import androidx.recyclerview.widget.GridLayoutManager
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
8 | import com.sasuke.launcheroneplus.di.scope.PerActivityScope
9 | import com.sasuke.launcheroneplus.ui.base.BaseEdgeEffectFactory
10 | import com.sasuke.launcheroneplus.ui.base.SpaceItemDecoration
11 | import com.sasuke.launcheroneplus.ui.hidden_apps.HiddenAppsActivityViewModel
12 | import com.sasuke.launcheroneplus.ui.launcher.all_apps.AppAdapter
13 | import com.sasuke.launcheroneplus.util.Constants
14 | import dagger.Binds
15 | import dagger.Module
16 | import dagger.Provides
17 | import dagger.multibindings.IntoMap
18 |
19 | @Module
20 | abstract class HiddenAppsActivityModule {
21 |
22 | companion object {
23 |
24 | @Provides
25 | @PerActivityScope
26 | fun adapter(glide: RequestManager): AppAdapter {
27 | return AppAdapter(glide)
28 | }
29 |
30 | @Provides
31 | @PerActivityScope
32 | fun gridLayoutManager(context: Context): GridLayoutManager {
33 | return GridLayoutManager(context, Constants.APP_LIST_SPAN_COUNT)
34 | }
35 |
36 | @Provides
37 | @PerActivityScope
38 | fun itemDecorator(): SpaceItemDecoration {
39 | return SpaceItemDecoration(
40 | Constants.GRID_HORIZONTAL_SPACING,
41 | Constants.GRID_VERTICAL_SPACING
42 | )
43 | }
44 |
45 | @Provides
46 | @PerActivityScope
47 | fun baseEdgeEffectFactory(): BaseEdgeEffectFactory {
48 | return BaseEdgeEffectFactory()
49 | }
50 | }
51 |
52 | @Binds
53 | @IntoMap
54 | @ViewModelKey(HiddenAppsActivityViewModel::class)
55 | abstract fun bindHiddenAppsActivityViewModel(hiddenAppsActivityViewModel: HiddenAppsActivityViewModel): ViewModel
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/wallpaper/list/pager/WallpaperPagerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.wallpaper.list.pager
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import android.widget.ImageView
6 | import androidx.recyclerview.widget.RecyclerView
7 | import com.bumptech.glide.RequestManager
8 | import com.sasuke.launcheroneplus.R
9 | import com.sasuke.launcheroneplus.data.model.Result
10 |
11 | class WallpaperPagerAdapter(private val glide: RequestManager) :
12 | RecyclerView.Adapter(), WallpaperPagerViewHolder.OnItemListener {
13 |
14 | val wallpapers = ArrayList()
15 | private lateinit var onItemListener: OnItemListener
16 |
17 |
18 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WallpaperPagerViewHolder {
19 | val view =
20 | LayoutInflater.from(parent.context)
21 | .inflate(R.layout.cell_wallpaper_pager, parent, false)
22 | val holder = WallpaperPagerViewHolder(
23 | view,
24 | glide
25 | )
26 | holder.setOnItemListener(this)
27 | return holder
28 | }
29 |
30 | override fun getItemCount(): Int {
31 | return wallpapers.size
32 | }
33 |
34 | override fun onBindViewHolder(holder: WallpaperPagerViewHolder, position: Int) {
35 | if (wallpapers.isNotEmpty() && position < wallpapers.size) {
36 | holder.setWallpaper(wallpapers[position])
37 | }
38 | }
39 |
40 | fun addWallpapers(list: List) {
41 | wallpapers.addAll(list)
42 | }
43 |
44 | interface OnItemListener {
45 | fun onItemClick(position: Int, result: Result, imageView: ImageView)
46 | }
47 |
48 | fun setOnItemListener(onItemListener: OnItemListener) {
49 | this.onItemListener = onItemListener
50 | }
51 |
52 | override fun onItemClick(position: Int, result: Result, imageView: ImageView) {
53 | if (::onItemListener.isInitialized)
54 | onItemListener.onItemClick(position, result, imageView)
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/receiver/AppChangeReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.receiver
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import com.sasuke.launcheroneplus.LauncherApp
7 | import com.sasuke.launcheroneplus.util.AppListUtil
8 | import kotlinx.coroutines.Dispatchers
9 | import kotlinx.coroutines.GlobalScope
10 | import kotlinx.coroutines.launch
11 | import kotlinx.coroutines.withContext
12 |
13 | class AppChangeReceiver : BroadcastReceiver() {
14 |
15 | override fun onReceive(context: Context?, intent: Intent?) {
16 | context?.let {
17 | LauncherApp.get(it.applicationContext).getComponent().getAllListUtils().let { appListUtil ->
18 | intent?.let { intent ->
19 | intent.action?.let {
20 | when (it) {
21 | Intent.ACTION_PACKAGE_ADDED -> {
22 | intent.data?.encodedSchemeSpecificPart?.let {
23 | GlobalScope.launch {
24 | withContext(Dispatchers.IO) {
25 | appListUtil.addAppToDB(it)
26 | }
27 | }
28 | }
29 | }
30 | Intent.ACTION_PACKAGE_REMOVED -> {
31 | intent.data?.encodedSchemeSpecificPart?.let {
32 | GlobalScope.launch {
33 | withContext(Dispatchers.IO) {
34 | appListUtil.removeAppFromDB(it)
35 | }
36 | }
37 | }
38 | }
39 | else -> {
40 | }
41 | }
42 | }
43 | }
44 |
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_wallpaper_preview.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
24 |
25 |
34 |
35 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
32 |
33 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/wallpaper/list/pager/WallpaperPagerActivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.wallpaper.list.pager
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import com.sasuke.launcheroneplus.data.model.Error
7 | import com.sasuke.launcheroneplus.data.model.Resource
8 | import com.sasuke.launcheroneplus.data.model.Result
9 | import com.sasuke.launcheroneplus.data.model.Wallpaper
10 | import com.sasuke.launcheroneplus.data.network.UnsplashRepository
11 | import javax.inject.Inject
12 |
13 | class WallpaperPagerActivityViewModel @Inject constructor(private val unsplashRepository: UnsplashRepository) :
14 | ViewModel(), UnsplashRepository.OnGetWallpaperListener,
15 | UnsplashRepository.OnGetPopularListener {
16 |
17 | private val _popularWallpaperLiveData = MutableLiveData>>()
18 | val popularWallpaperLiveData: LiveData>>
19 | get() = _popularWallpaperLiveData
20 |
21 | private val _wallpaperLiveData = MutableLiveData>>()
22 | val wallpaperLiveData: LiveData>>
23 | get() = _wallpaperLiveData
24 |
25 | fun getWallpapersForQuery(query: String, page: Int) {
26 | _wallpaperLiveData.postValue(Resource.loading())
27 | unsplashRepository.getWallpapers(query, page, this)
28 | }
29 |
30 | fun getPopularWalls() {
31 | _popularWallpaperLiveData.postValue(Resource.loading())
32 | unsplashRepository.getPopular(this)
33 | }
34 |
35 | override fun onGetWallpaperSuccess(wallpaper: Wallpaper) {
36 | _wallpaperLiveData.postValue(Resource.success(wallpaper.results))
37 | }
38 |
39 | override fun onGetWallpaperFailure(error: Error) {
40 | _wallpaperLiveData.postValue(Resource.error(error))
41 | }
42 |
43 | override fun onGetPopularSuccess(list: List) {
44 | _popularWallpaperLiveData.postValue(Resource.success(list))
45 | }
46 |
47 | override fun onGetPopularFailure(error: Error) {
48 | _popularWallpaperLiveData.postValue(Resource.error(error))
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/KeyboardTriggerBehavior.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.app.Activity
4 | import android.graphics.Rect
5 | import android.view.View
6 | import android.view.ViewTreeObserver
7 | import androidx.lifecycle.LifecycleOwner
8 | import androidx.lifecycle.LiveData
9 | import androidx.lifecycle.Observer
10 |
11 | open class KeyboardTriggerBehavior(activity: Activity, private val minKeyboardHeight: Int = 0) : LiveData() {
12 | enum class Status {
13 | OPEN, CLOSED
14 | }
15 |
16 | private val contentView: View = activity.findViewById(android.R.id.content)
17 |
18 | private val globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
19 | val displayRect = Rect().apply { contentView.getWindowVisibleDisplayFrame(this) }
20 | val keypadHeight = contentView.rootView.height - displayRect.bottom
21 | if (keypadHeight > minKeyboardHeight) {
22 | setDistinctValue(Status.OPEN)
23 | } else {
24 | setDistinctValue(Status.CLOSED)
25 | }
26 | }
27 |
28 | override fun observe(owner: LifecycleOwner, observer: Observer) {
29 | super.observe(owner, observer)
30 | observersUpdated()
31 | }
32 |
33 | override fun observeForever(observer: Observer) {
34 | super.observeForever(observer)
35 | observersUpdated()
36 | }
37 |
38 | override fun removeObservers(owner: LifecycleOwner) {
39 | super.removeObservers(owner)
40 | observersUpdated()
41 | }
42 |
43 | override fun removeObserver(observer: Observer) {
44 | super.removeObserver(observer)
45 | observersUpdated()
46 | }
47 |
48 | private fun setDistinctValue(newValue: Status) {
49 | if (value != newValue) {
50 | value = newValue
51 | }
52 | }
53 |
54 | private fun observersUpdated() {
55 | if (hasObservers()) {
56 | contentView.viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener)
57 | } else {
58 | contentView.viewTreeObserver.removeOnGlobalLayoutListener(globalLayoutListener)
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/SharedPreferencesSettingsLiveData.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.content.SharedPreferences
4 | import android.text.TextUtils
5 | import androidx.lifecycle.LiveData
6 | import com.google.gson.Gson
7 | import com.sasuke.launcheroneplus.data.model.SettingPreference
8 |
9 | class SharedPreferencesSettingsLiveData(
10 | sharedPrefs: SharedPreferences,
11 | private val gson: Gson
12 | ) :
13 | SharedPreferencesLiveData(sharedPrefs) {
14 |
15 | private fun getString(key: String, default: String): String {
16 | sharedPrefs.getString(key, default)?.let {
17 | return it
18 | } ?: run {
19 | return ""
20 | }
21 | }
22 |
23 | private fun getString(key: String): String {
24 | return getString(key, "")
25 | }
26 |
27 | override fun getValueFromPreferences(key: String): SettingPreference? {
28 | var user: SettingPreference? = null
29 | try {
30 | val userString = getString(Constants.PREFERENCES)
31 | if (!TextUtils.isEmpty(userString)) {
32 | user = gson.fromJson(userString, SettingPreference::class.java)
33 | }
34 | } catch (e: Exception) {
35 | e.printStackTrace()
36 | } finally {
37 | return user
38 | }
39 | }
40 | }
41 |
42 | abstract class SharedPreferencesLiveData(val sharedPrefs: SharedPreferences) : LiveData() {
43 | private val preferenceChangeListener =
44 | SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
45 | if (key == Constants.PREFERENCES) {
46 | value = getValueFromPreferences(key)
47 | }
48 | }
49 |
50 | abstract fun getValueFromPreferences(key: String): T?
51 |
52 | override fun onActive() {
53 | super.onActive()
54 | value = getValueFromPreferences(Constants.PREFERENCES)
55 | sharedPrefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
56 | }
57 |
58 | override fun onInactive() {
59 | sharedPrefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
60 | super.onInactive()
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/Extensions.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.content.Context
4 | import android.content.pm.ApplicationInfo
5 | import android.content.res.Resources
6 | import android.graphics.drawable.Drawable
7 | import android.view.View
8 | import androidx.core.graphics.drawable.DrawableCompat
9 | import androidx.core.view.WindowInsetsCompat
10 | import androidx.recyclerview.widget.RecyclerView
11 | import java.io.File
12 | import java.util.*
13 |
14 | fun String.toLowerCased(): String = this.toLowerCase(Locale.getDefault())
15 |
16 | inline fun RecyclerView.forEachVisibleHolder(
17 | action: (T) -> Unit
18 | ) {
19 | for (i in 0 until childCount) {
20 | action(getChildViewHolder(getChildAt(i)) as T)
21 | }
22 | }
23 |
24 | fun Drawable.updateTint(color: Int) {
25 | DrawableCompat.wrap(this)?.let {
26 | DrawableCompat.setTint(it, color)
27 | }
28 | }
29 |
30 | fun Context.getIconFolderPath(label: String): String {
31 | return "${applicationContext.getExternalFilesDir(Constants.ICON_FOLDER_NAME)}${File.separator}${label.removeSpecialChars()}"
32 | }
33 |
34 | fun isSystemApp(context: Context, packageName: String): Boolean {
35 | val appInfo = context.applicationContext.packageManager.getApplicationInfo(packageName, 0)
36 | return (appInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0
37 | }
38 |
39 | fun String.removeSpecialChars(): String {
40 | return replace(
41 | "[\\W]|_".toRegex(),
42 | ""
43 | )
44 | }
45 |
46 | fun View.hide() {
47 | this.visibility = View.GONE
48 | }
49 |
50 | fun View.show() {
51 | this.visibility = View.VISIBLE
52 | }
53 |
54 | fun Int.dpToPx(): Int {
55 | return (this * Resources.getSystem().displayMetrics.density).toInt()
56 | }
57 |
58 | fun Int.alphaPercentage(): Int {
59 | return ((this.toDouble() / 100.0) * 255.0).toInt()
60 | }
61 |
62 | val View.keyboardIsVisible: Boolean
63 | get() = WindowInsetsCompat
64 | .toWindowInsetsCompat(rootWindowInsets)
65 | .isVisible(WindowInsetsCompat.Type.ime())
66 |
67 | fun T.removeItemDecorations() {
68 | while (itemDecorationCount > 0) {
69 | removeItemDecorationAt(0)
70 | }
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/wallpaper/list/grid/WallpaperActivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.wallpaper.list.grid
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import com.sasuke.launcheroneplus.data.model.Error
7 | import com.sasuke.launcheroneplus.data.model.Resource
8 | import com.sasuke.launcheroneplus.data.model.Result
9 | import com.sasuke.launcheroneplus.data.model.Wallpaper
10 | import com.sasuke.launcheroneplus.data.network.UnsplashRepository
11 | import javax.inject.Inject
12 |
13 | class WallpaperActivityViewModel @Inject constructor(private val unsplashRepository: UnsplashRepository) :
14 | ViewModel(), UnsplashRepository.OnGetWallpaperListener,
15 | UnsplashRepository.OnGetPopularListener {
16 |
17 | var page = 1
18 |
19 | private val _popularWallpaperLiveData = MutableLiveData>>()
20 | val popularWallpaperLiveData: LiveData>>
21 | get() = _popularWallpaperLiveData
22 |
23 | private val _wallpaperLiveData = MutableLiveData>>()
24 | val wallpaperLiveData: LiveData>>
25 | get() = _wallpaperLiveData
26 |
27 | fun getWallpapersForQuery(query: String) {
28 | _wallpaperLiveData.postValue(Resource.loading())
29 | unsplashRepository.getWallpapers(query, page, this)
30 | }
31 |
32 | fun getPopularWalls() {
33 | _popularWallpaperLiveData.postValue(Resource.loading())
34 | unsplashRepository.getPopular(this)
35 | }
36 |
37 | fun refresh() {
38 | page = 1
39 | }
40 |
41 | override fun onGetWallpaperSuccess(wallpaper: Wallpaper) {
42 | page++
43 | _wallpaperLiveData.postValue(Resource.success(wallpaper.results))
44 | }
45 |
46 | override fun onGetWallpaperFailure(error: Error) {
47 | _wallpaperLiveData.postValue(Resource.error(error))
48 | }
49 |
50 | override fun onGetPopularSuccess(list: List) {
51 | _popularWallpaperLiveData.postValue(Resource.success(list))
52 | }
53 |
54 | override fun onGetPopularFailure(error: Error) {
55 | _popularWallpaperLiveData.postValue(Resource.error(error))
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/util/AppListUtil.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.util
2 |
3 | import android.content.Context
4 | import android.content.pm.PackageManager
5 | import androidx.annotation.WorkerThread
6 | import com.sasuke.launcheroneplus.data.db.RoomRepository
7 | import com.sasuke.launcheroneplus.data.model.App
8 | import javax.inject.Inject
9 |
10 | class AppListUtil @Inject constructor(
11 | private val roomRepository: RoomRepository,
12 | private val bitmapUtils: BitmapUtils,
13 | private val storageUtils: StorageUtils,
14 | private val packageManager: PackageManager,
15 | private val context: Context
16 | ) {
17 |
18 | @WorkerThread
19 | suspend fun saveAppsInDB() {
20 | if (roomRepository.isAppsInDB() <= 0) {
21 | val list = PackageResolverUtils.getSortedAppList(packageManager)
22 | list.forEach { appInfo ->
23 | bitmapUtils.drawableToBitmap(appInfo.icon)?.let {
24 | if (appInfo.packageName != context.packageName) {
25 | storageUtils.saveBitmapToFile(it, appInfo.label)
26 | roomRepository.insert(
27 | App(
28 | packageName = appInfo.packageName,
29 | label = appInfo.label
30 | )
31 | )
32 | }
33 | }
34 | }
35 | }
36 | }
37 |
38 | @WorkerThread
39 | suspend fun removeAppFromDB(packageName: String) {
40 | roomRepository.deleteApp(packageName)
41 | }
42 |
43 | @WorkerThread
44 | suspend fun addAppToDB(packageName: String) {
45 | PackageResolverUtils.getAppInfoFromPackageName(packageManager, packageName)
46 | ?.let { appInfo ->
47 | bitmapUtils.drawableToBitmap(appInfo.icon)?.let {
48 | storageUtils.saveBitmapToFile(it, appInfo.label)
49 | roomRepository.insert(
50 | App(
51 | packageName = appInfo.packageName,
52 | label = appInfo.label
53 | )
54 | )
55 | }
56 | }
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_wallpaper_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
26 |
27 |
38 |
39 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/cell_app_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
24 |
25 |
38 |
39 |
58 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/ActivityBindingModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import com.sasuke.launcheroneplus.ui.launcher.LauncherActivity
4 | import com.sasuke.launcheroneplus.di.scope.PerActivityScope
5 | import com.sasuke.launcheroneplus.ui.hidden_apps.HiddenAppsActivity
6 | import com.sasuke.launcheroneplus.ui.hidden_apps.app_selector.AppSelectionActivity
7 | import com.sasuke.launcheroneplus.ui.screen_off.ScreenOffActivity
8 | import com.sasuke.launcheroneplus.ui.settings.LauncherSettingsActivity
9 | import com.sasuke.launcheroneplus.ui.settings.app_drawer.AppDrawerActivity
10 | import com.sasuke.launcheroneplus.ui.wallpaper.WallpaperPreviewActivity
11 | import com.sasuke.launcheroneplus.ui.wallpaper.list.grid.WallpaperGridActivity
12 | import com.sasuke.launcheroneplus.ui.wallpaper.list.pager.WallpaperPagerActivity
13 | import dagger.Module
14 | import dagger.android.ContributesAndroidInjector
15 |
16 | @Module(includes = [])
17 | abstract class ActivityBindingModule {
18 |
19 | @PerActivityScope
20 | @ContributesAndroidInjector(modules = [LauncherActivityModule::class])
21 | internal abstract fun mainActivity(): LauncherActivity
22 |
23 | @PerActivityScope
24 | @ContributesAndroidInjector(modules = [HiddenAppsActivityModule::class])
25 | internal abstract fun hiddenAppsActivity(): HiddenAppsActivity
26 |
27 | @PerActivityScope
28 | @ContributesAndroidInjector(modules = [AppSelectionActivityModule::class])
29 | internal abstract fun appSelectionActivity(): AppSelectionActivity
30 |
31 | @PerActivityScope
32 | @ContributesAndroidInjector(modules = [])
33 | internal abstract fun screenOffActivity(): ScreenOffActivity
34 |
35 | @PerActivityScope
36 | @ContributesAndroidInjector(modules = [WallpaperActivityModule::class])
37 | internal abstract fun wallpaperSettingsActivity(): WallpaperGridActivity
38 |
39 | @PerActivityScope
40 | @ContributesAndroidInjector(modules = [WallpaperPagerActivityModule::class])
41 | internal abstract fun wallpaperPagerActivity(): WallpaperPagerActivity
42 |
43 | @PerActivityScope
44 | @ContributesAndroidInjector(modules = [])
45 | internal abstract fun wallpaperPreviewActivity(): WallpaperPreviewActivity
46 |
47 | @PerActivityScope
48 | @ContributesAndroidInjector(modules = [LauncherSettingsActivityModule::class])
49 | internal abstract fun launcherSettingsActivity(): LauncherSettingsActivity
50 |
51 | @PerActivityScope
52 | @ContributesAndroidInjector(modules = [AppDrawerActivityModule::class])
53 | internal abstract fun appDrawerActivity(): AppDrawerActivity
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/component/LauncherAppComponent.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.component
2 |
3 | import android.content.Context
4 | import com.bumptech.glide.RequestManager
5 | import com.google.gson.Gson
6 | import com.sasuke.launcheroneplus.LauncherApp
7 | import com.sasuke.launcheroneplus.data.db.RoomRepository
8 | import com.sasuke.launcheroneplus.data.network.UnsplashRepository
9 | import com.sasuke.launcheroneplus.di.scope.LauncherAppScope
10 | import com.sasuke.launcheroneplus.di.module.util.ViewModelFactoryModule
11 | import com.sasuke.launcheroneplus.di.module.activity.ActivityBindingModule
12 | import com.sasuke.launcheroneplus.di.module.application.LauncherApplicationModule
13 | import com.sasuke.launcheroneplus.di.module.library.GlideModule
14 | import com.sasuke.launcheroneplus.di.module.network.UnsplashRepositoryModule
15 | import com.sasuke.launcheroneplus.di.module.util.SharedPreferenceModule
16 | import com.sasuke.launcheroneplus.di.module.util.UtilsModule
17 | import com.sasuke.launcheroneplus.util.*
18 | import dagger.BindsInstance
19 | import dagger.Component
20 | import dagger.android.AndroidInjector
21 | import dagger.android.support.AndroidSupportInjectionModule
22 | import io.github.inflationx.calligraphy3.CalligraphyInterceptor
23 | import timber.log.Timber
24 |
25 | @LauncherAppScope
26 | @Component(
27 | modules = [
28 | LauncherApplicationModule::class,
29 | UnsplashRepositoryModule::class,
30 | GlideModule::class,
31 | UtilsModule::class,
32 | SharedPreferenceModule::class,
33 | AndroidSupportInjectionModule::class,
34 | ViewModelFactoryModule::class,
35 | ActivityBindingModule::class]
36 | )
37 | interface LauncherAppComponent : AndroidInjector {
38 |
39 | @Component.Factory
40 | interface Factory {
41 | fun create(@BindsInstance applicationContext: Context): LauncherAppComponent
42 | }
43 |
44 | fun context(): Context
45 |
46 | fun glide(): RequestManager
47 |
48 | fun getStorageUtil(): StorageUtils
49 |
50 | fun getBitmapUtils(): BitmapUtils
51 |
52 | fun getRoomRepository(): RoomRepository
53 |
54 | fun getAllListUtils(): AppListUtil
55 |
56 | fun getUnsplashRepository(): UnsplashRepository
57 |
58 | fun timberTree(): Timber.Tree
59 |
60 | fun calligraphyInterceptor(): CalligraphyInterceptor
61 |
62 | fun getSettingUtils(): SettingUtils
63 |
64 | fun getColorUtils(): ColorUtils
65 |
66 | fun getSharedPreferenceUtil(): SharedPreferenceUtil
67 |
68 | fun getSharedPreferencesSettingsLiveData(): SharedPreferencesSettingsLiveData
69 |
70 | fun gson(): Gson
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/di/module/activity/AppSelectionActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.di.module.activity
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.ViewModel
5 | import androidx.recyclerview.widget.GridLayoutManager
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.di.mapkey.ViewModelKey
8 | import com.sasuke.launcheroneplus.di.qualifiers.HiddenAppLayoutManager
9 | import com.sasuke.launcheroneplus.di.qualifiers.VisibleAppLayoutManager
10 | import com.sasuke.launcheroneplus.di.scope.PerActivityScope
11 | import com.sasuke.launcheroneplus.ui.base.SpaceItemDecoration
12 | import com.sasuke.launcheroneplus.ui.hidden_apps.app_selector.AppSelectionActivityViewModel
13 | import com.sasuke.launcheroneplus.ui.hidden_apps.app_selector.HiddenAppSelectionAdapter
14 | import com.sasuke.launcheroneplus.ui.hidden_apps.app_selector.VisibleAppSelectionAdapter
15 | import com.sasuke.launcheroneplus.util.Constants
16 | import dagger.Binds
17 | import dagger.Module
18 | import dagger.Provides
19 | import dagger.multibindings.IntoMap
20 |
21 | @Module
22 | abstract class AppSelectionActivityModule {
23 |
24 | companion object {
25 |
26 | @Provides
27 | @PerActivityScope
28 | fun hiddenAppSelectionAdapter(glide: RequestManager): HiddenAppSelectionAdapter {
29 | return HiddenAppSelectionAdapter(glide)
30 | }
31 |
32 | @Provides
33 | @PerActivityScope
34 | fun visibleAppSelectionAdapter(glide: RequestManager): VisibleAppSelectionAdapter {
35 | return VisibleAppSelectionAdapter(glide)
36 | }
37 |
38 | @Provides
39 | @PerActivityScope
40 | @HiddenAppLayoutManager
41 | fun gridLayoutManager1(context: Context): GridLayoutManager {
42 | return GridLayoutManager(context, Constants.APP_LIST_SPAN_COUNT)
43 | }
44 |
45 | @Provides
46 | @PerActivityScope
47 | @VisibleAppLayoutManager
48 | fun gridLayoutManager2(context: Context): GridLayoutManager {
49 | return GridLayoutManager(context, Constants.APP_LIST_SPAN_COUNT)
50 | }
51 |
52 | @Provides
53 | @PerActivityScope
54 | fun itemDecorator(): SpaceItemDecoration {
55 | return SpaceItemDecoration(
56 | Constants.GRID_HORIZONTAL_SPACING,
57 | Constants.GRID_VERTICAL_SPACING
58 | )
59 | }
60 | }
61 |
62 | @Binds
63 | @IntoMap
64 | @ViewModelKey(AppSelectionActivityViewModel::class)
65 | abstract fun bindAppSelectionActivityViewModel(appSelectionActivityViewModel: AppSelectionActivityViewModel): ViewModel
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/drag_drop/GridViewAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.drag_drop
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import android.widget.BaseAdapter
7 | import com.bumptech.glide.RequestManager
8 | import com.huxq17.handygridview.scrollrunner.OnItemMovedListener
9 | import com.sasuke.launcheroneplus.R
10 | import com.sasuke.launcheroneplus.data.model.App
11 |
12 | class GridViewAdapter(private val glide: RequestManager) : BaseAdapter(), OnItemMovedListener,
13 | GridAppViewHolder.OnClickListeners {
14 |
15 | private lateinit var onClickListeners: OnClickListeners
16 | private val list: MutableList = ArrayList()
17 | private var inEditMode = false
18 |
19 | companion object {
20 | private const val MAX_ALLOWED_SHORTCUTS = 19
21 | }
22 |
23 | override fun getView(position: Int, convertview: View?, parent: ViewGroup): View {
24 | val appViewHolder: GridAppViewHolder
25 | val myView: View =
26 | convertview
27 | ?: LayoutInflater.from(parent.context).inflate(
28 | R.layout.cell_app_info,
29 | parent,
30 | false
31 | )
32 | appViewHolder = GridAppViewHolder(myView, glide)
33 | appViewHolder.setAppInfo(getItem(position) as App)
34 | appViewHolder.setOnClickListeners(this)
35 | return myView
36 | }
37 |
38 | override fun getItem(position: Int): Any {
39 | return list[position]
40 | }
41 |
42 | override fun getItemId(position: Int): Long {
43 | return position.toLong()
44 | }
45 |
46 | override fun getCount(): Int {
47 | return list.size
48 | }
49 |
50 | override fun onItemMoved(from: Int, to: Int) {
51 | val appInfo = list.removeAt(from)
52 | list.add(to, appInfo)
53 | }
54 |
55 | override fun isFixed(position: Int): Boolean {
56 | return false
57 | }
58 |
59 | fun addItem(appInfo: App) {
60 | if (list.size > MAX_ALLOWED_SHORTCUTS)
61 | list.removeAt(0)
62 | list.add(appInfo)
63 | notifyDataSetChanged()
64 | }
65 |
66 | fun setInEditMode(inEditMode: Boolean) {
67 | this.inEditMode = inEditMode
68 | notifyDataSetChanged()
69 | }
70 |
71 | interface OnClickListeners {
72 | fun onItemClick(position: Int, parent: View, appInfo: App)
73 | }
74 |
75 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
76 | this.onClickListeners = onClickListeners
77 | }
78 |
79 | override fun onItemClick(position: Int, parent: View, appInfo: App) {
80 | if (::onClickListeners.isInitialized)
81 | onClickListeners.onItemClick(position, parent, appInfo)
82 | }
83 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/color_picker/ColorAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.color_picker
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.R
8 | import com.sasuke.launcheroneplus.data.model.DefaultColor
9 |
10 | class ColorAdapter : RecyclerView.Adapter(),
11 | ColorViewHolder.OnClickListeners {
12 |
13 | private lateinit var colors: List
14 | private lateinit var onClickListeners: OnClickListeners
15 |
16 | private var position = -1
17 |
18 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColorViewHolder {
19 | val view =
20 | LayoutInflater.from(parent.context).inflate(R.layout.cell_default_color, parent, false)
21 | val holder = ColorViewHolder(view)
22 | holder.setOnClickListeners(this)
23 | return holder
24 | }
25 |
26 | override fun getItemCount(): Int {
27 | return if (::colors.isInitialized) colors.size else 0
28 | }
29 |
30 | override fun onBindViewHolder(holder: ColorViewHolder, position: Int) {
31 | if (::colors.isInitialized) {
32 | holder.setColor(colors[position])
33 | }
34 | }
35 |
36 | override fun onBindViewHolder(
37 | holder: ColorViewHolder,
38 | position: Int,
39 | payloads: MutableList
40 | ) {
41 | if (::colors.isInitialized) {
42 | if (payloads.isNotEmpty()) {
43 | val flag = payloads[0] as Boolean
44 | holder.toggle(flag)
45 | } else {
46 | super.onBindViewHolder(holder, position, payloads)
47 | }
48 | }
49 | }
50 |
51 | interface OnClickListeners {
52 | fun onItemClick(position: Int, color: Int)
53 | }
54 |
55 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
56 | this.onClickListeners = onClickListeners
57 | }
58 |
59 | override fun onItemClick(position: Int, color: Int) {
60 | if (::onClickListeners.isInitialized)
61 | onClickListeners.onItemClick(position, color)
62 | }
63 |
64 | fun setColors(list: List) {
65 | this.colors = list
66 | notifyDataSetChanged()
67 | }
68 |
69 | fun toggle(position: Int): Boolean {
70 | if (this.position != -1 && this.position != position) {
71 | colors[this.position].isSelected = false
72 | notifyItemChanged(this.position, false)
73 | this.position = position
74 | } else {
75 | this.position = position
76 | }
77 | var flag = colors[position].isSelected
78 | flag = !flag
79 | colors[position].isSelected = flag
80 | notifyItemChanged(position, flag)
81 | return flag
82 | }
83 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/launcher/recent_apps/RecentAppAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.launcher.recent_apps
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.core.view.doOnLayout
7 | import androidx.recyclerview.widget.DiffUtil
8 | import androidx.recyclerview.widget.ListAdapter
9 | import com.bumptech.glide.RequestManager
10 | import com.sasuke.launcheroneplus.R
11 | import com.sasuke.launcheroneplus.data.model.App
12 | import com.sasuke.launcheroneplus.ui.launcher.all_apps.AppViewHolder
13 | import com.sasuke.launcheroneplus.util.OnCustomEventListeners
14 |
15 | class RecentAppAdapter(private val glide: RequestManager) :
16 | ListAdapter(appItemDiffCallback), OnCustomEventListeners {
17 |
18 | private lateinit var onClickListeners: OnCustomEventListeners
19 |
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
21 | val view =
22 | LayoutInflater.from(parent.context).inflate(R.layout.cell_app_info, parent, false)
23 | return AppViewHolder(view, glide).apply {
24 | // The rotation pivot should be at the center of the top edge.
25 | itemView.doOnLayout { v -> v.pivotX = v.width / 2f }
26 | itemView.pivotY = 0f
27 | setOnCustomEventListeners(this@RecentAppAdapter)
28 | }
29 | }
30 |
31 | override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
32 | getItem(position)?.let {
33 | holder.setAppInfo(it)
34 | }
35 | }
36 |
37 | fun setOnClickListeners(onClickListeners: OnCustomEventListeners) {
38 | this.onClickListeners = onClickListeners
39 | }
40 |
41 | override fun onItemClick(position: Int, parent: View, appInfo: App) {
42 | if (::onClickListeners.isInitialized)
43 | onClickListeners.onItemClick(position, parent, appInfo)
44 | }
45 |
46 | override fun onItemLongClick(position: Int, parent: View, appInfo: App) {
47 | if (::onClickListeners.isInitialized)
48 | onClickListeners.onItemLongClick(position, parent, appInfo)
49 | }
50 |
51 | override fun onDragStart(position: Int, parent: View, appInfo: App) {
52 | if (::onClickListeners.isInitialized)
53 | onClickListeners.onDragStart(position, parent, appInfo)
54 | }
55 |
56 | override fun onEventCancel(position: Int, appInfo: App) {
57 | if (::onClickListeners.isInitialized)
58 | onClickListeners.onEventCancel(position, appInfo)
59 | }
60 | }
61 |
62 | private val appItemDiffCallback = object : DiffUtil.ItemCallback() {
63 | override fun areItemsTheSame(oldItem: App, newItem: App): Boolean {
64 | return oldItem.packageName == newItem.packageName
65 | }
66 |
67 | override fun areContentsTheSame(oldItem: App, newItem: App): Boolean {
68 | return oldItem == newItem
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/launcher/recent_apps/RecentAppSectionViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.launcher.recent_apps
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.GridLayoutManager
5 | import androidx.recyclerview.widget.LinearLayoutManager
6 | import androidx.recyclerview.widget.RecyclerView
7 | import com.bumptech.glide.RequestManager
8 | import com.sasuke.launcheroneplus.data.model.App
9 | import com.sasuke.launcheroneplus.data.model.DrawerStyle
10 | import com.sasuke.launcheroneplus.ui.base.BaseViewHolder
11 | import com.sasuke.launcheroneplus.util.Constants
12 | import com.sasuke.launcheroneplus.util.OnCustomEventListeners
13 | import com.sasuke.launcheroneplus.util.hide
14 | import com.sasuke.launcheroneplus.util.show
15 | import kotlinx.android.synthetic.main.cell_recent_app_section.view.*
16 |
17 | class RecentAppSectionViewHolder(
18 | itemView: View,
19 | private val glide: RequestManager,
20 | private val drawerStyle: DrawerStyle
21 | ) :
22 | BaseViewHolder(itemView), OnCustomEventListeners {
23 |
24 | private lateinit var recentAppAdapter: RecentAppAdapter
25 | private lateinit var onCustomEventListeners: OnCustomEventListeners
26 |
27 | fun setRecentApps(list: List) {
28 | when (drawerStyle) {
29 | DrawerStyle.VERTICAL -> {
30 | itemView.separator.show()
31 | }
32 | DrawerStyle.LIST -> {
33 | itemView.separator.hide()
34 | }
35 | }
36 | itemView.rvRecentApps.layoutManager =
37 | GridLayoutManager(
38 | itemView.context,
39 | Constants.APP_LIST_SPAN_COUNT,
40 | RecyclerView.VERTICAL,
41 | false
42 | )
43 | recentAppAdapter = RecentAppAdapter(glide)
44 | recentAppAdapter.setOnClickListeners(this)
45 | itemView.rvRecentApps.adapter = recentAppAdapter
46 | recentAppAdapter.submitList(list)
47 | }
48 |
49 | fun setOnCustomEventListener(onCustomEventListeners: OnCustomEventListeners) {
50 | this.onCustomEventListeners = onCustomEventListeners
51 | }
52 |
53 | override fun onItemClick(position: Int, parent: View, appInfo: App) {
54 | if (::onCustomEventListeners.isInitialized)
55 | onCustomEventListeners.onItemClick(position, parent, appInfo)
56 | }
57 |
58 | override fun onItemLongClick(position: Int, parent: View, appInfo: App) {
59 | if (::onCustomEventListeners.isInitialized)
60 | onCustomEventListeners.onItemLongClick(position, parent, appInfo)
61 | }
62 |
63 | override fun onDragStart(position: Int, parent: View, appInfo: App) {
64 | if (::onCustomEventListeners.isInitialized)
65 | onCustomEventListeners.onDragStart(position, parent, appInfo)
66 | }
67 |
68 | override fun onEventCancel(position: Int, appInfo: App) {
69 | if (::onCustomEventListeners.isInitialized)
70 | onCustomEventListeners.onEventCancel(position, appInfo)
71 | }
72 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/hidden_apps/app_selector/HiddenAppSelectionAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.hidden_apps.app_selector
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.bumptech.glide.RequestManager
7 | import com.sasuke.launcheroneplus.R
8 | import com.sasuke.launcheroneplus.data.model.App
9 |
10 | class HiddenAppSelectionAdapter(private val glide: RequestManager) :
11 | RecyclerView.Adapter(),
12 | HiddenAppSelectionViewHolder.OnClickListeners {
13 |
14 | private lateinit var onClickListeners: OnClickListeners
15 | private lateinit var appList: MutableList
16 |
17 | init {
18 | setHasStableIds(true)
19 | }
20 |
21 | override fun onCreateViewHolder(
22 | parent: ViewGroup,
23 | viewType: Int
24 | ): HiddenAppSelectionViewHolder {
25 | val view =
26 | LayoutInflater.from(parent.context).inflate(R.layout.cell_app_selector, parent, false)
27 | val holderHidden = HiddenAppSelectionViewHolder(view, glide)
28 | holderHidden.setOnClickListeners(this)
29 | return holderHidden
30 | }
31 |
32 | override fun getItemCount(): Int {
33 | return if (::appList.isInitialized) appList.size else 0
34 | }
35 |
36 | override fun onBindViewHolder(holderHidden: HiddenAppSelectionViewHolder, position: Int) {
37 | if (::appList.isInitialized) {
38 | holderHidden.setApp(appList[position])
39 | }
40 | }
41 |
42 | override fun onBindViewHolder(
43 | holderHidden: HiddenAppSelectionViewHolder,
44 | position: Int,
45 | payloads: MutableList
46 | ) {
47 | super.onBindViewHolder(holderHidden, position, payloads)
48 | if (payloads.isNotEmpty()) {
49 | val flag = payloads[0]
50 | if (flag is Boolean) {
51 | holderHidden.toggle(flag)
52 | }
53 | }
54 | }
55 |
56 | override fun getItemId(position: Int): Long {
57 | return position.toLong()
58 | }
59 |
60 | interface OnClickListeners {
61 | fun onHiddenItemClick(position: Int, appInfo: App)
62 | }
63 |
64 | fun setApps(list: MutableList) {
65 | this.appList = list
66 | notifyDataSetChanged()
67 | }
68 |
69 | fun toggle(position: Int) {
70 | var flag = appList[position].isHidden
71 | flag = !flag
72 | appList[position].isHidden = flag
73 | notifyItemChanged(position, flag)
74 | }
75 |
76 | fun setOnClickListeners(onClickListeners: OnClickListeners) {
77 | this.onClickListeners = onClickListeners
78 | }
79 |
80 | override fun onHiddenItemClick(position: Int, appInfo: App) {
81 | if (::onClickListeners.isInitialized)
82 | onClickListeners.onHiddenItemClick(position, appInfo)
83 | }
84 |
85 | // override fun getSectionText(position: Int): CharSequence {
86 | // return appList[position].label[0].toUpperCase().toString()
87 | // }
88 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sasuke/launcheroneplus/ui/settings/app_drawer/AppDrawerActivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sasuke.launcheroneplus.ui.settings.app_drawer
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.viewModelScope
5 | import com.google.gson.Gson
6 | import com.sasuke.launcheroneplus.data.model.DrawerStyle
7 | import com.sasuke.launcheroneplus.util.Constants
8 | import com.sasuke.launcheroneplus.util.SharedPreferenceUtil
9 | import kotlinx.coroutines.Dispatchers
10 | import kotlinx.coroutines.launch
11 | import kotlinx.coroutines.withContext
12 | import javax.inject.Inject
13 |
14 | class AppDrawerActivityViewModel @Inject constructor(
15 | private val sharedPreferenceUtil: SharedPreferenceUtil,
16 | private val gson: Gson
17 | ) :
18 | ViewModel() {
19 |
20 | fun setFastScrollState(isEnabled: Boolean) {
21 | viewModelScope.launch {
22 | withContext(Dispatchers.IO) {
23 | sharedPreferenceUtil.getSettingPreference()?.let {
24 | it.isFastScrollEnabled = isEnabled
25 | sharedPreferenceUtil.putString(Constants.PREFERENCES, gson.toJson(it))
26 | }
27 | }
28 | }
29 | }
30 |
31 | fun setDrawerStyle(style: String) {
32 | var indicator = DrawerStyle.VERTICAL
33 | when (style) {
34 | DrawerStyle.VERTICAL.name -> indicator = DrawerStyle.VERTICAL
35 | DrawerStyle.LIST.name -> indicator = DrawerStyle.LIST
36 | }
37 | viewModelScope.launch {
38 | withContext(Dispatchers.IO) {
39 | sharedPreferenceUtil.getSettingPreference()?.let {
40 | it.drawerStyle = indicator
41 | sharedPreferenceUtil.putString(Constants.PREFERENCES, gson.toJson(it))
42 | }
43 | }
44 | }
45 | }
46 |
47 | fun setPrimaryColor(color: Int) {
48 | viewModelScope.launch {
49 | withContext(Dispatchers.IO) {
50 | sharedPreferenceUtil.getSettingPreference()?.let {
51 | it.primaryColor = color
52 | sharedPreferenceUtil.putString(Constants.PREFERENCES, gson.toJson(it))
53 | }
54 | }
55 | }
56 | }
57 |
58 | fun setBackgroundColor(color: Int) {
59 | viewModelScope.launch {
60 | withContext(Dispatchers.IO) {
61 | sharedPreferenceUtil.getSettingPreference()?.let {
62 | it.backgroundColor = color
63 | sharedPreferenceUtil.putString(Constants.PREFERENCES, gson.toJson(it))
64 | }
65 | }
66 | }
67 | }
68 |
69 | fun setBackgroundTransparency(transparency: Int) {
70 | viewModelScope.launch {
71 | withContext(Dispatchers.IO) {
72 | sharedPreferenceUtil.getSettingPreference()?.let {
73 | it.backgroundColorAlpha = 100 - transparency
74 | sharedPreferenceUtil.putString(Constants.PREFERENCES, gson.toJson(it))
75 | }
76 | }
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------