Refactor: Worked out a better way for moving around the app.
Changed from using ViewPager2 for changing apps of the app. Added animations for changing to different fragments of the app
This commit is contained in:
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||||
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
|
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
<uses-permission
|
||||||
|
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="32" />
|
android:maxSdkVersion="32" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||||
@@ -13,11 +14,11 @@
|
|||||||
tools:ignore="QueryAllPackagesPermission" />
|
tools:ignore="QueryAllPackagesPermission" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
||||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
||||||
<uses-permission android:name="android.permission.BIND_APPWIDGET"
|
<uses-permission
|
||||||
|
android:name="android.permission.BIND_APPWIDGET"
|
||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
@@ -34,10 +35,6 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Launcher">
|
android:theme="@style/Theme.Launcher">
|
||||||
<activity
|
|
||||||
android:name=".ui.activities.SettingsActivity"
|
|
||||||
android:exported="false" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activities.LauncherActivity"
|
android:name=".ui.activities.LauncherActivity"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
@@ -95,13 +92,14 @@
|
|||||||
android:resource="@xml/policies" />
|
android:resource="@xml/policies" />
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
|
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
|
||||||
|
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".accessibility.MyAccessibilityService"
|
android:name=".accessibility.ActionService"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:label="@string/app_name"
|
android:label="@string/accessibility_service_name"
|
||||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.accessibilityservice"
|
android:name="android.accessibilityservice"
|
||||||
|
|||||||
@@ -65,5 +65,4 @@ object Constants {
|
|||||||
const val APP_WIDGET_HOST_ID = 1024
|
const val APP_WIDGET_HOST_ID = 1024
|
||||||
const val TRIPLE_TAP_DELAY_MS = 300
|
const val TRIPLE_TAP_DELAY_MS = 300
|
||||||
const val LONG_PRESS_DELAY_MS = 500
|
const val LONG_PRESS_DELAY_MS = 500
|
||||||
const val REQUEST_CODE_ENABLE_ADMIN = 123
|
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ import com.github.droidworksstudio.launcher.R
|
|||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
class MyAccessibilityService : AccessibilityService() {
|
class ActionService : AccessibilityService() {
|
||||||
|
|
||||||
private var info: AccessibilityServiceInfo = AccessibilityServiceInfo()
|
private var info: AccessibilityServiceInfo = AccessibilityServiceInfo()
|
||||||
|
|
||||||
@@ -20,7 +20,8 @@ class MyAccessibilityService : AccessibilityService() {
|
|||||||
mInstance = WeakReference(this)
|
mInstance = WeakReference(this)
|
||||||
|
|
||||||
info.apply {
|
info.apply {
|
||||||
eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED or AccessibilityEvent.TYPE_VIEW_FOCUSED
|
eventTypes =
|
||||||
|
AccessibilityEvent.TYPE_VIEW_CLICKED or AccessibilityEvent.TYPE_VIEW_FOCUSED
|
||||||
|
|
||||||
feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
|
feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
|
||||||
|
|
||||||
@@ -95,8 +96,8 @@ class MyAccessibilityService : AccessibilityService() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
private var mInstance: WeakReference<MyAccessibilityService> = WeakReference(null)
|
private var mInstance: WeakReference<ActionService> = WeakReference(null)
|
||||||
fun instance(): MyAccessibilityService? {
|
fun instance(): ActionService? {
|
||||||
return mInstance.get()
|
return mInstance.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ import androidx.appcompat.widget.LinearLayoutCompat
|
|||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.github.droidworksstudio.launcher.Constants
|
import com.github.droidworksstudio.launcher.Constants
|
||||||
import com.github.droidworksstudio.launcher.R
|
import com.github.droidworksstudio.launcher.R
|
||||||
import com.github.droidworksstudio.launcher.accessibility.MyAccessibilityService
|
import com.github.droidworksstudio.launcher.accessibility.ActionService
|
||||||
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
||||||
import com.github.droidworksstudio.launcher.ui.activities.FakeHomeActivity
|
import com.github.droidworksstudio.launcher.ui.activities.FakeHomeActivity
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
@@ -95,8 +95,8 @@ class AppHelper @Inject constructor() {
|
|||||||
.invoke(context.getSystemService(Constants.NOTIFICATION_SERVICE))
|
.invoke(context.getSystemService(Constants.NOTIFICATION_SERVICE))
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
MyAccessibilityService.runAccessibilityMode(context)
|
ActionService.runAccessibilityMode(context)
|
||||||
MyAccessibilityService.instance()?.openNotifications()
|
ActionService.instance()?.openNotifications()
|
||||||
}
|
}
|
||||||
exception.printStackTrace()
|
exception.printStackTrace()
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,8 @@ class AppHelper @Inject constructor() {
|
|||||||
.invoke(context.getSystemService(Constants.QUICKSETTINGS_SERVICE))
|
.invoke(context.getSystemService(Constants.QUICKSETTINGS_SERVICE))
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
MyAccessibilityService.runAccessibilityMode(context)
|
ActionService.runAccessibilityMode(context)
|
||||||
MyAccessibilityService.instance()?.openQuickSettings()
|
ActionService.instance()?.openQuickSettings()
|
||||||
}
|
}
|
||||||
exception.printStackTrace()
|
exception.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.github.droidworksstudio.launcher.helper
|
package com.github.droidworksstudio.launcher.helper
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.biometric.BiometricManager
|
import androidx.biometric.BiometricManager
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.github.droidworksstudio.launcher.R
|
import com.github.droidworksstudio.launcher.R
|
||||||
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -56,32 +56,46 @@ class FingerprintHelper @Inject constructor(private val fragment: Fragment) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startFingerprintSettingsAuth(targetClass: Class<*>) {
|
fun startFingerprintSettingsAuth(runNavigation: Int) {
|
||||||
val executor = ContextCompat.getMainExecutor(fragment.requireContext())
|
val executor = ContextCompat.getMainExecutor(fragment.requireContext())
|
||||||
|
|
||||||
val biometricPrompt = BiometricPrompt(fragment, executor, object : BiometricPrompt.AuthenticationCallback() {
|
val biometricPrompt =
|
||||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
BiometricPrompt(fragment, executor, object : BiometricPrompt.AuthenticationCallback() {
|
||||||
sendToTargetActivity(targetClass)
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||||
}
|
fragment.findNavController().navigate(runNavigation)
|
||||||
|
|
||||||
override fun onAuthenticationFailed() {
|
|
||||||
appHelper.showToast(fragment.requireContext(), fragment.getString(R.string.authentication_failed))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAuthenticationError(errorCode: Int, errorMessage: CharSequence) {
|
|
||||||
when (errorCode) {
|
|
||||||
BiometricPrompt.ERROR_USER_CANCELED -> appHelper.showToast(fragment.requireContext(), fragment.getString(R.string.authentication_cancel))
|
|
||||||
else -> appHelper.showToast(fragment.requireContext(), fragment.getString(R.string.authentication_error).format(errorMessage, errorCode))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
override fun onAuthenticationFailed() {
|
||||||
|
appHelper.showToast(
|
||||||
|
fragment.requireContext(),
|
||||||
|
fragment.getString(R.string.authentication_failed)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationError(errorCode: Int, errorMessage: CharSequence) {
|
||||||
|
when (errorCode) {
|
||||||
|
BiometricPrompt.ERROR_USER_CANCELED -> appHelper.showToast(
|
||||||
|
fragment.requireContext(),
|
||||||
|
fragment.getString(R.string.authentication_cancel)
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> appHelper.showToast(
|
||||||
|
fragment.requireContext(),
|
||||||
|
fragment.getString(R.string.authentication_error)
|
||||||
|
.format(errorMessage, errorCode)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
val promptInfoBuilder = BiometricPrompt.PromptInfo.Builder()
|
val promptInfoBuilder = BiometricPrompt.PromptInfo.Builder()
|
||||||
.setTitle(fragment.getString(R.string.authentication_title))
|
.setTitle(fragment.getString(R.string.authentication_title))
|
||||||
.setSubtitle(fragment.getString(R.string.authentication_subtitle))
|
.setSubtitle(fragment.getString(R.string.authentication_subtitle))
|
||||||
|
|
||||||
val authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
val authenticators =
|
||||||
val canAuthenticate = BiometricManager.from(fragment.requireContext()).canAuthenticate(authenticators)
|
BiometricManager.Authenticators.BIOMETRIC_WEAK or BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
||||||
|
val canAuthenticate =
|
||||||
|
BiometricManager.from(fragment.requireContext()).canAuthenticate(authenticators)
|
||||||
|
|
||||||
if (canAuthenticate == BiometricManager.BIOMETRIC_SUCCESS) {
|
if (canAuthenticate == BiometricManager.BIOMETRIC_SUCCESS) {
|
||||||
promptInfoBuilder.setAllowedAuthenticators(authenticators)
|
promptInfoBuilder.setAllowedAuthenticators(authenticators)
|
||||||
@@ -95,17 +109,23 @@ class FingerprintHelper @Inject constructor(private val fragment: Fragment) {
|
|||||||
BiometricManager.BIOMETRIC_SUCCESS -> biometricPrompt.authenticate(promptInfo)
|
BiometricManager.BIOMETRIC_SUCCESS -> biometricPrompt.authenticate(promptInfo)
|
||||||
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
|
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
|
||||||
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
|
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
|
||||||
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> sendToTargetActivity(targetClass)
|
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> sendToTarget(runNavigation)
|
||||||
else -> appHelper.showToast(fragment.requireContext(), fragment.getString(R.string.authentication_failed))
|
|
||||||
|
else -> appHelper.showToast(
|
||||||
|
fragment.requireContext(),
|
||||||
|
fragment.getString(R.string.authentication_failed)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendToTargetActivity(targetClass: Class<*>) {
|
private fun sendToTarget(runNavigation: Int) {
|
||||||
try {
|
try {
|
||||||
val intent = Intent(fragment.requireActivity(), targetClass)
|
fragment.findNavController().navigate(runNavigation)
|
||||||
fragment.requireActivity().startActivity(intent)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
appHelper.showToast(fragment.requireContext(), fragment.getString(R.string.authentication_failed))
|
appHelper.showToast(
|
||||||
|
fragment.requireContext(),
|
||||||
|
fragment.getString(R.string.authentication_failed)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ internal open class OnSwipeTouchListener(c: Context?) : OnTouchListener {
|
|||||||
open fun onLongClick() {}
|
open fun onLongClick() {}
|
||||||
open fun onDoubleClick() {}
|
open fun onDoubleClick() {}
|
||||||
open fun onTripleClick() {}
|
open fun onTripleClick() {}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
gestureDetector = GestureDetector(c, GestureListener())
|
gestureDetector = GestureDetector(c, GestureListener())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package com.github.droidworksstudio.launcher.ui.activities
|
package com.github.droidworksstudio.launcher.ui.activities
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.admin.DevicePolicyManager
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -15,6 +18,7 @@ import androidx.navigation.findNavController
|
|||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.navigateUp
|
import androidx.navigation.ui.navigateUp
|
||||||
|
import com.github.droidworksstudio.launcher.Constants
|
||||||
import com.github.droidworksstudio.launcher.R
|
import com.github.droidworksstudio.launcher.R
|
||||||
import com.github.droidworksstudio.launcher.databinding.ActivityMainBinding
|
import com.github.droidworksstudio.launcher.databinding.ActivityMainBinding
|
||||||
import com.github.droidworksstudio.launcher.helper.AppHelper
|
import com.github.droidworksstudio.launcher.helper.AppHelper
|
||||||
@@ -143,5 +147,4 @@ class MainActivity : AppCompatActivity() {
|
|||||||
if (navController.currentDestination?.id != R.id.HomeFragment)
|
if (navController.currentDestination?.id != R.id.HomeFragment)
|
||||||
navController.popBackStack(R.id.HomeFragment, false)
|
navController.popBackStack(R.id.HomeFragment, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package com.github.droidworksstudio.launcher.ui.activities
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.navigation.findNavController
|
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
|
||||||
import androidx.navigation.ui.navigateUp
|
|
||||||
import com.github.droidworksstudio.launcher.R
|
|
||||||
import com.github.droidworksstudio.launcher.databinding.ActivitySettingsBinding
|
|
||||||
import com.github.droidworksstudio.launcher.helper.AppHelper
|
|
||||||
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
|
||||||
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class SettingsActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
private lateinit var binding: ActivitySettingsBinding
|
|
||||||
|
|
||||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
|
||||||
|
|
||||||
private val preferenceViewModel: PreferenceViewModel by viewModels()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var preferenceHelper: PreferenceHelper
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var appHelper: AppHelper
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
|
|
||||||
binding = ActivitySettingsBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
|
|
||||||
// Find the NavHostFragment
|
|
||||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_settings) as NavHostFragment
|
|
||||||
|
|
||||||
// Retrieve the NavController
|
|
||||||
val navController = navHostFragment.navController
|
|
||||||
appBarConfiguration = AppBarConfiguration(navController.graph)
|
|
||||||
|
|
||||||
initializeDependencies()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSupportNavigateUp(): Boolean {
|
|
||||||
val navController = findNavController(R.id.nav_host_fragment_content_settings)
|
|
||||||
return navController.navigateUp(appBarConfiguration)
|
|
||||||
|| super.onSupportNavigateUp()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initializeDependencies() {
|
|
||||||
|
|
||||||
preferenceViewModel.setShowStatusBar(preferenceHelper.showStatusBar)
|
|
||||||
}
|
|
||||||
private fun observeUI(){
|
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
|
||||||
|
|
||||||
preferenceViewModel.setShowStatusBar(preferenceHelper.showStatusBar)
|
|
||||||
preferenceViewModel.showStatusBarLiveData.observe(this) {
|
|
||||||
if (it) appHelper.showStatusBar(this.window)
|
|
||||||
else appHelper.hideStatusBar(this.window) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
observeUI()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,9 +10,10 @@ import com.github.droidworksstudio.launcher.databinding.ItemDrawBinding
|
|||||||
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
|
|
||||||
class DrawAdapter(private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
class DrawAdapter(
|
||||||
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
||||||
private val preferenceHelperProvider: PreferenceHelper
|
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
||||||
|
private val preferenceHelperProvider: PreferenceHelper
|
||||||
) :
|
) :
|
||||||
ListAdapter<AppInfo, RecyclerView.ViewHolder>(DiffCallback()) {
|
ListAdapter<AppInfo, RecyclerView.ViewHolder>(DiffCallback()) {
|
||||||
|
|
||||||
@@ -27,7 +28,12 @@ class DrawAdapter(private val onAppClickedListener: OnItemClickedListener.OnApps
|
|||||||
)
|
)
|
||||||
val preferenceHelper = preferenceHelperProvider
|
val preferenceHelper = preferenceHelperProvider
|
||||||
|
|
||||||
return DrawViewHolder(binding, onAppClickedListener, onAppLongClickedListener, preferenceHelper)
|
return DrawViewHolder(
|
||||||
|
binding,
|
||||||
|
onAppClickedListener,
|
||||||
|
onAppLongClickedListener,
|
||||||
|
preferenceHelper
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
@@ -36,7 +42,7 @@ class DrawAdapter(private val onAppClickedListener: OnItemClickedListener.OnApps
|
|||||||
(holder as DrawViewHolder).bind(appInfo)
|
(holder as DrawViewHolder).bind(appInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiffCallback : DiffUtil.ItemCallback<AppInfo>() {
|
class DiffCallback : DiffUtil.ItemCallback<AppInfo>() {
|
||||||
override fun areItemsTheSame(oldItem: AppInfo, newItem: AppInfo) =
|
override fun areItemsTheSame(oldItem: AppInfo, newItem: AppInfo) =
|
||||||
oldItem.id == newItem.id
|
oldItem.id == newItem.id
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ import javax.inject.Inject
|
|||||||
* A simple [Fragment] subclass as the second destination in the navigation.
|
* A simple [Fragment] subclass as the second destination in the navigation.
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
class DrawFragment : Fragment(),
|
||||||
|
OnItemClickedListener.OnAppsClickedListener,
|
||||||
OnItemClickedListener.OnAppLongClickedListener,
|
OnItemClickedListener.OnAppLongClickedListener,
|
||||||
OnItemClickedListener.BottomSheetDismissListener,
|
OnItemClickedListener.BottomSheetDismissListener,
|
||||||
OnItemClickedListener.OnAppStateClickListener,
|
OnItemClickedListener.OnAppStateClickListener,
|
||||||
@@ -143,7 +144,8 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
private fun observeSwipeTouchListener() {
|
private fun observeSwipeTouchListener() {
|
||||||
binding.mainView.setOnTouchListener(getSwipeGestureListener(context))
|
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
|
binding.drawAdapter.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
|
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ import com.github.droidworksstudio.launcher.databinding.ItemDrawBinding
|
|||||||
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
|
|
||||||
class DrawViewHolder(private val binding: ItemDrawBinding,
|
class DrawViewHolder(
|
||||||
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
private val binding: ItemDrawBinding,
|
||||||
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
||||||
private val preferenceHelper: PreferenceHelper):
|
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
||||||
|
private val preferenceHelper: PreferenceHelper
|
||||||
|
) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
fun bind(appInfo: AppInfo) {
|
fun bind(appInfo: AppInfo) {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ import com.github.droidworksstudio.launcher.databinding.ItemFavoriteBinding
|
|||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemMoveListener
|
import com.github.droidworksstudio.launcher.listener.OnItemMoveListener
|
||||||
|
|
||||||
class FavoriteAdapter(private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
class FavoriteAdapter(
|
||||||
) : ListAdapter<AppInfo, RecyclerView.ViewHolder>(DiffCallback()) ,OnItemMoveListener.OnItemActionListener{
|
private val onAppClickedListener:
|
||||||
|
OnItemClickedListener.OnAppsClickedListener,
|
||||||
|
) : ListAdapter<AppInfo, RecyclerView.ViewHolder>(DiffCallback()),
|
||||||
|
OnItemMoveListener.OnItemActionListener {
|
||||||
|
|
||||||
private lateinit var touchHelper: ItemTouchHelper
|
private lateinit var touchHelper: ItemTouchHelper
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
@@ -24,6 +25,7 @@ import com.github.droidworksstudio.launcher.helper.FingerprintHelper
|
|||||||
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemMoveListener
|
import com.github.droidworksstudio.launcher.listener.OnItemMoveListener
|
||||||
|
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
|
||||||
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
|
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -32,7 +34,8 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
class FavoriteFragment : Fragment(),
|
||||||
|
OnItemClickedListener.OnAppsClickedListener,
|
||||||
OnItemClickedListener.BottomSheetDismissListener,
|
OnItemClickedListener.BottomSheetDismissListener,
|
||||||
OnItemClickedListener.OnAppStateClickListener,
|
OnItemClickedListener.OnAppStateClickListener,
|
||||||
OnItemMoveListener.OnItemActionListener,
|
OnItemMoveListener.OnItemActionListener,
|
||||||
@@ -77,6 +80,7 @@ class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener
|
|||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
observeFavorite()
|
observeFavorite()
|
||||||
observeHomeAppOrder()
|
observeHomeAppOrder()
|
||||||
|
observeSwipeTouchListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
@@ -101,6 +105,14 @@ class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun observeFavorite() {
|
||||||
|
viewModel.compareInstalledAppInfo()
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewModel.favoriteApps.collect {
|
||||||
|
favoriteAdapter.submitList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeHomeAppOrder() {
|
private fun observeHomeAppOrder() {
|
||||||
binding.favoriteAdapter.adapter = favoriteAdapter
|
binding.favoriteAdapter.adapter = favoriteAdapter
|
||||||
@@ -165,11 +177,22 @@ class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener
|
|||||||
itemTouchHelper.attachToRecyclerView(binding.favoriteAdapter)
|
itemTouchHelper.attachToRecyclerView(binding.favoriteAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeFavorite() {
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
viewModel.compareInstalledAppInfo()
|
private fun observeSwipeTouchListener() {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
viewModel.favoriteApps.collect {
|
binding.favoriteAdapter.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
favoriteAdapter.submitList(it)
|
}
|
||||||
|
|
||||||
|
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
|
||||||
|
return object : OnSwipeTouchListener(context) {
|
||||||
|
override fun onSwipeLeft() {
|
||||||
|
super.onSwipeLeft()
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight() {
|
||||||
|
super.onSwipeRight()
|
||||||
|
findNavController().popBackStack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ import com.github.droidworksstudio.launcher.databinding.ItemFavoriteBinding
|
|||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
class FavoriteViewHolder(private val binding: ItemFavoriteBinding,
|
class FavoriteViewHolder(
|
||||||
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
private val binding: ItemFavoriteBinding,
|
||||||
private val touchHelper: ItemTouchHelper,
|
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
||||||
|
private val touchHelper: ItemTouchHelper,
|
||||||
) :
|
) :
|
||||||
RecyclerView.ViewHolder(binding.root){
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
binding.appFavoriteDragIcon.setOnTouchListener { _, event ->
|
binding.appFavoriteDragIcon.setOnTouchListener { _, event ->
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
import com.github.droidworksstudio.launcher.R
|
import com.github.droidworksstudio.launcher.R
|
||||||
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
||||||
@@ -19,13 +20,15 @@ import com.github.droidworksstudio.launcher.databinding.FragmentHiddenBinding
|
|||||||
import com.github.droidworksstudio.launcher.helper.AppHelper
|
import com.github.droidworksstudio.launcher.helper.AppHelper
|
||||||
import com.github.droidworksstudio.launcher.helper.FingerprintHelper
|
import com.github.droidworksstudio.launcher.helper.FingerprintHelper
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
|
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
|
||||||
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
|
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
|
||||||
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
|
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class HiddenFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
class HiddenFragment : Fragment(),
|
||||||
|
OnItemClickedListener.OnAppsClickedListener,
|
||||||
OnItemClickedListener.OnAppLongClickedListener,
|
OnItemClickedListener.OnAppLongClickedListener,
|
||||||
OnItemClickedListener.BottomSheetDismissListener,
|
OnItemClickedListener.BottomSheetDismissListener,
|
||||||
OnItemClickedListener.OnAppStateClickListener,
|
OnItemClickedListener.OnAppStateClickListener,
|
||||||
@@ -65,6 +68,7 @@ class HiddenFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
observeHiddenApps()
|
observeHiddenApps()
|
||||||
|
observeSwipeTouchListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
@@ -86,6 +90,26 @@ class HiddenFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
private fun observeSwipeTouchListener() {
|
||||||
|
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
|
binding.hiddenAdapter.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
|
||||||
|
return object : OnSwipeTouchListener(context) {
|
||||||
|
override fun onSwipeLeft() {
|
||||||
|
super.onSwipeLeft()
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight() {
|
||||||
|
super.onSwipeRight()
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeBioAuthCheck(appInfo: AppInfo) {
|
private fun observeBioAuthCheck(appInfo: AppInfo) {
|
||||||
if (!appInfo.lock) {
|
if (!appInfo.lock) {
|
||||||
appHelper.launchApp(context, appInfo)
|
appHelper.launchApp(context, appInfo)
|
||||||
|
|||||||
@@ -6,23 +6,25 @@ import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
|||||||
import com.github.droidworksstudio.launcher.databinding.ItemHiddenBinding
|
import com.github.droidworksstudio.launcher.databinding.ItemHiddenBinding
|
||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
|
|
||||||
class HiddenViewHolder(private val binding: ItemHiddenBinding,
|
class HiddenViewHolder(
|
||||||
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
private val binding: ItemHiddenBinding,
|
||||||
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener) :
|
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
||||||
|
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener
|
||||||
|
) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
fun bind(appInfo: AppInfo) {
|
fun bind(appInfo: AppInfo) {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
appHiddenName.text = appInfo.appName
|
appHiddenName.text = appInfo.appName
|
||||||
Log.d("Tag", "Draw Adapter: ${appInfo.appName}")
|
Log.d("Tag", "Draw Adapter: ${appInfo.appName}")
|
||||||
}
|
}
|
||||||
|
|
||||||
itemView.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
onAppClickedListener.onAppClicked(appInfo)
|
onAppClickedListener.onAppClicked(appInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemView.setOnLongClickListener {
|
itemView.setOnLongClickListener {
|
||||||
onAppLongClickedListener.onAppLongClicked(appInfo)
|
onAppLongClickedListener.onAppLongClicked(appInfo)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,11 +11,12 @@ import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
|||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeAdapter @Inject constructor(private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
class HomeAdapter @Inject constructor(
|
||||||
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
||||||
private val preferenceHelperProvider: PreferenceHelper
|
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
||||||
|
private val preferenceHelperProvider: PreferenceHelper
|
||||||
) :
|
) :
|
||||||
ListAdapter<AppInfo,RecyclerView.ViewHolder>(DiffCallback()) {
|
ListAdapter<AppInfo, RecyclerView.ViewHolder>(DiffCallback()) {
|
||||||
|
|
||||||
override fun onCreateViewHolder(
|
override fun onCreateViewHolder(
|
||||||
parent: android.view.ViewGroup,
|
parent: android.view.ViewGroup,
|
||||||
@@ -28,7 +29,12 @@ class HomeAdapter @Inject constructor(private val onAppClickedListener: OnItemCl
|
|||||||
)
|
)
|
||||||
val preferenceHelper = preferenceHelperProvider
|
val preferenceHelper = preferenceHelperProvider
|
||||||
|
|
||||||
return HomeViewHolder(binding, onAppClickedListener, onAppLongClickedListener, preferenceHelper)
|
return HomeViewHolder(
|
||||||
|
binding,
|
||||||
|
onAppClickedListener,
|
||||||
|
onAppLongClickedListener,
|
||||||
|
preferenceHelper
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
@@ -37,7 +43,7 @@ class HomeAdapter @Inject constructor(private val onAppClickedListener: OnItemCl
|
|||||||
(holder as HomeViewHolder).bind(appInfo)
|
(holder as HomeViewHolder).bind(appInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiffCallback : DiffUtil.ItemCallback<AppInfo>() {
|
class DiffCallback : DiffUtil.ItemCallback<AppInfo>() {
|
||||||
override fun areItemsTheSame(oldItem: AppInfo, newItem: AppInfo) =
|
override fun areItemsTheSame(oldItem: AppInfo, newItem: AppInfo) =
|
||||||
oldItem.id == newItem.id
|
oldItem.id == newItem.id
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
import com.github.droidworksstudio.launcher.R
|
import com.github.droidworksstudio.launcher.R
|
||||||
import com.github.droidworksstudio.launcher.accessibility.MyAccessibilityService
|
import com.github.droidworksstudio.launcher.accessibility.ActionService
|
||||||
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
import com.github.droidworksstudio.launcher.data.entities.AppInfo
|
||||||
import com.github.droidworksstudio.launcher.databinding.FragmentHomeBinding
|
import com.github.droidworksstudio.launcher.databinding.FragmentHomeBinding
|
||||||
import com.github.droidworksstudio.launcher.helper.AppHelper
|
import com.github.droidworksstudio.launcher.helper.AppHelper
|
||||||
@@ -30,7 +30,6 @@ import com.github.droidworksstudio.launcher.helper.hideKeyboard
|
|||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
|
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
|
||||||
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
||||||
import com.github.droidworksstudio.launcher.ui.activities.SettingsActivity
|
|
||||||
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
|
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
|
||||||
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
|
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
|
||||||
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
|
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
|
||||||
@@ -46,7 +45,8 @@ import javax.inject.Inject
|
|||||||
* A simple [Fragment] subclass as the default destination in the navigation.
|
* A simple [Fragment] subclass as the default destination in the navigation.
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
class HomeFragment : Fragment(),
|
||||||
|
OnItemClickedListener.OnAppsClickedListener,
|
||||||
OnItemClickedListener.OnAppLongClickedListener,
|
OnItemClickedListener.OnAppLongClickedListener,
|
||||||
OnItemClickedListener.BottomSheetDismissListener,
|
OnItemClickedListener.BottomSheetDismissListener,
|
||||||
OnItemClickedListener.OnAppStateClickListener,
|
OnItemClickedListener.OnAppStateClickListener,
|
||||||
@@ -91,16 +91,16 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
initializeInjectedDependencies()
|
initializeInjectedDependencies()
|
||||||
initSwipeTouchListener()
|
|
||||||
setupBattery()
|
setupBattery()
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
observeSwipeTouchListener()
|
||||||
observeUserInterfaceSettings()
|
observeUserInterfaceSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
private fun initializeInjectedDependencies() {
|
private fun initializeInjectedDependencies() {
|
||||||
context = requireContext()
|
context = requireContext()
|
||||||
binding.mainView.hideKeyboard()
|
binding.nestScrollView.hideKeyboard()
|
||||||
|
|
||||||
binding.nestScrollView.scrollEventListener = this
|
binding.nestScrollView.scrollEventListener = this
|
||||||
|
|
||||||
@@ -111,15 +111,6 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
preferenceViewModel.setShowDailyWord(preferenceHelper.showDailyWord)
|
preferenceViewModel.setShowDailyWord(preferenceHelper.showDailyWord)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
|
||||||
private fun initSwipeTouchListener() {
|
|
||||||
binding.nestScrollView.setOnTouchListener(getSwipeGestureListener(context))
|
|
||||||
|
|
||||||
binding.clock.setOnClickListener { appHelper.launchClock(context) }
|
|
||||||
binding.date.setOnClickListener { appHelper.launchCalendar(context) }
|
|
||||||
binding.battery.setOnClickListener { appHelper.openBatteryManager(context) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupBattery() {
|
private fun setupBattery() {
|
||||||
batteryReceiver = object : BroadcastReceiver() {
|
batteryReceiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
@@ -163,8 +154,18 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
private fun observeSwipeTouchListener() {
|
||||||
|
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
|
binding.nestScrollView.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
|
|
||||||
|
binding.clock.setOnClickListener { appHelper.launchClock(context) }
|
||||||
|
binding.date.setOnClickListener { appHelper.launchCalendar(context) }
|
||||||
|
binding.battery.setOnClickListener { appHelper.openBatteryManager(context) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeUserInterfaceSettings() {
|
private fun observeUserInterfaceSettings() {
|
||||||
binding.mainView.hideKeyboard()
|
binding.nestScrollView.hideKeyboard()
|
||||||
|
|
||||||
preferenceViewModel.setShowTime(preferenceHelper.showTime)
|
preferenceViewModel.setShowTime(preferenceHelper.showTime)
|
||||||
preferenceViewModel.setShowDate(preferenceHelper.showDate)
|
preferenceViewModel.setShowDate(preferenceHelper.showDate)
|
||||||
@@ -226,10 +227,13 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun observeBioAuthCheck(appInfo: AppInfo) {
|
private fun observeBioAuthCheck(appInfo: AppInfo) {
|
||||||
if (!appInfo.lock) appHelper.launchApp(
|
if (!appInfo.lock)
|
||||||
context,
|
appHelper.launchApp(
|
||||||
appInfo
|
context,
|
||||||
) else fingerHelper.startFingerprintAuth(appInfo, this)
|
appInfo
|
||||||
|
)
|
||||||
|
else
|
||||||
|
fingerHelper.startFingerprintAuth(appInfo, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSelectedApp(appInfo: AppInfo) {
|
private fun showSelectedApp(appInfo: AppInfo) {
|
||||||
@@ -252,8 +256,8 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
override fun onDoubleClick() {
|
override fun onDoubleClick() {
|
||||||
super.onDoubleClick()
|
super.onDoubleClick()
|
||||||
if (preferenceHelper.tapLockScreen) {
|
if (preferenceHelper.tapLockScreen) {
|
||||||
MyAccessibilityService.runAccessibilityMode(context)
|
ActionService.runAccessibilityMode(context)
|
||||||
MyAccessibilityService.instance()?.lockScreen()
|
ActionService.instance()?.lockScreen()
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -267,7 +271,6 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
override fun onSwipeRight() {
|
override fun onSwipeRight() {
|
||||||
super.onSwipeRight()
|
super.onSwipeRight()
|
||||||
findNavController().navigate(R.id.action_HomeFragment_to_FavoriteFragment)
|
findNavController().navigate(R.id.action_HomeFragment_to_FavoriteFragment)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSwipeDown() {
|
override fun onSwipeDown() {
|
||||||
@@ -320,7 +323,7 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (preferenceHelper.settingsLock) {
|
if (preferenceHelper.settingsLock) {
|
||||||
fingerHelper.startFingerprintSettingsAuth(SettingsActivity::class.java)
|
fingerHelper.startFingerprintSettingsAuth(R.id.action_HomeFragment_to_SettingsFragment)
|
||||||
} else {
|
} else {
|
||||||
findNavController().navigate(R.id.action_HomeFragment_to_SettingsFragment)
|
findNavController().navigate(R.id.action_HomeFragment_to_SettingsFragment)
|
||||||
}
|
}
|
||||||
@@ -335,12 +338,12 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
|
|||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
binding.mainView.hideKeyboard()
|
binding.nestScrollView.hideKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
binding.mainView.hideKeyboard()
|
binding.nestScrollView.hideKeyboard()
|
||||||
observeUserInterfaceSettings()
|
observeUserInterfaceSettings()
|
||||||
observeFavoriteAppList()
|
observeFavoriteAppList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.github.droidworksstudio.launcher.ui.home
|
package com.github.droidworksstudio.launcher.ui.home
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -11,13 +12,13 @@ import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
|||||||
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
class HomeViewHolder @Inject constructor(
|
class HomeViewHolder @Inject constructor(
|
||||||
private val binding: ItemHomeBinding,
|
private val binding: ItemHomeBinding,
|
||||||
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
private val onAppClickedListener: OnItemClickedListener.OnAppsClickedListener,
|
||||||
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
|
||||||
private val preferenceHelper: PreferenceHelper,
|
private val preferenceHelper: PreferenceHelper,
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
fun bind(appInfo: AppInfo) {
|
fun bind(appInfo: AppInfo) {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
val layoutParams = LinearLayoutCompat.LayoutParams(
|
val layoutParams = LinearLayoutCompat.LayoutParams(
|
||||||
@@ -36,26 +37,33 @@ class HomeViewHolder @Inject constructor(
|
|||||||
Log.d("Tag", "Home Adapter Color: ${preferenceHelper.appColor}")
|
Log.d("Tag", "Home Adapter Color: ${preferenceHelper.appColor}")
|
||||||
|
|
||||||
if (preferenceHelper.showAppIcon) {
|
if (preferenceHelper.showAppIcon) {
|
||||||
val appIcon = binding.root.context.packageManager.getApplicationIcon(appInfo.packageName)
|
val appIcon =
|
||||||
|
binding.root.context.packageManager.getApplicationIcon(appInfo.packageName)
|
||||||
when (preferenceHelper.homeAppAlignment) {
|
when (preferenceHelper.homeAppAlignment) {
|
||||||
Gravity.START -> {
|
Gravity.START -> {
|
||||||
appHomeLeftIcon.setImageDrawable(appIcon)
|
appHomeLeftIcon.setImageDrawable(appIcon)
|
||||||
appHomeLeftIcon.layoutParams.width = preferenceHelper.appTextSize.toInt() * 3
|
appHomeLeftIcon.layoutParams.width =
|
||||||
appHomeLeftIcon.layoutParams.height = preferenceHelper.appTextSize.toInt() * 3
|
preferenceHelper.appTextSize.toInt() * 3
|
||||||
|
appHomeLeftIcon.layoutParams.height =
|
||||||
|
preferenceHelper.appTextSize.toInt() * 3
|
||||||
appHomeLeftIcon.visibility = View.VISIBLE
|
appHomeLeftIcon.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
Gravity.END -> {
|
Gravity.END -> {
|
||||||
appHomeRightIcon.setImageDrawable(appIcon)
|
appHomeRightIcon.setImageDrawable(appIcon)
|
||||||
appHomeRightIcon.layoutParams.width = preferenceHelper.appTextSize.toInt() * 3
|
appHomeRightIcon.layoutParams.width =
|
||||||
appHomeRightIcon.layoutParams.height = preferenceHelper.appTextSize.toInt() * 3
|
preferenceHelper.appTextSize.toInt() * 3
|
||||||
|
appHomeRightIcon.layoutParams.height =
|
||||||
|
preferenceHelper.appTextSize.toInt() * 3
|
||||||
appHomeRightIcon.visibility = View.VISIBLE
|
appHomeRightIcon.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
itemView.setOnClickListener { onAppClickedListener.onAppClicked(appInfo) }
|
itemView.setOnClickListener {
|
||||||
|
onAppClickedListener.onAppClicked(appInfo)
|
||||||
|
}
|
||||||
|
|
||||||
itemView.setOnLongClickListener {
|
itemView.setOnLongClickListener {
|
||||||
onAppLongClickedListener.onAppLongClicked(appInfo)
|
onAppLongClickedListener.onAppLongClicked(appInfo)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.github.droidworksstudio.launcher.ui.settings
|
package com.github.droidworksstudio.launcher.ui.settings
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -16,6 +17,7 @@ import com.github.droidworksstudio.launcher.databinding.FragmentSettingsBinding
|
|||||||
import com.github.droidworksstudio.launcher.helper.AppHelper
|
import com.github.droidworksstudio.launcher.helper.AppHelper
|
||||||
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
||||||
import com.github.droidworksstudio.launcher.helper.restartApp
|
import com.github.droidworksstudio.launcher.helper.restartApp
|
||||||
|
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
|
||||||
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
||||||
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AlignmentBottomSheetDialogFragment
|
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AlignmentBottomSheetDialogFragment
|
||||||
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.ColorBottomSheetDialogFragment
|
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.ColorBottomSheetDialogFragment
|
||||||
@@ -26,7 +28,8 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SettingsFragment : Fragment(), ScrollEventListener {
|
class SettingsFragment : Fragment(),
|
||||||
|
ScrollEventListener {
|
||||||
|
|
||||||
private var _binding: FragmentSettingsBinding? = null
|
private var _binding: FragmentSettingsBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
@@ -41,6 +44,8 @@ class SettingsFragment : Fragment(), ScrollEventListener {
|
|||||||
|
|
||||||
private lateinit var navController: NavController
|
private lateinit var navController: NavController
|
||||||
|
|
||||||
|
private lateinit var context: Context
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
@@ -59,8 +64,11 @@ class SettingsFragment : Fragment(), ScrollEventListener {
|
|||||||
appHelper.dayNightMod(requireContext(), binding.nestScrollView)
|
appHelper.dayNightMod(requireContext(), binding.nestScrollView)
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
context = requireContext()
|
||||||
|
|
||||||
initializeInjectedDependencies()
|
initializeInjectedDependencies()
|
||||||
observeClickListener()
|
observeClickListener()
|
||||||
|
observeSwipeTouchListener()
|
||||||
|
|
||||||
val packageInfo =
|
val packageInfo =
|
||||||
requireContext().packageManager.getPackageInfo(requireContext().packageName, 0)
|
requireContext().packageManager.getPackageInfo(requireContext().packageName, 0)
|
||||||
@@ -217,4 +225,24 @@ class SettingsFragment : Fragment(), ScrollEventListener {
|
|||||||
preferenceViewModel.setLockSettings(isChecked)
|
preferenceViewModel.setLockSettings(isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
private fun observeSwipeTouchListener() {
|
||||||
|
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
|
||||||
|
return object : OnSwipeTouchListener(context) {
|
||||||
|
override fun onSwipeLeft() {
|
||||||
|
super.onSwipeLeft()
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight() {
|
||||||
|
super.onSwipeRight()
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,8 @@ import javax.inject.Inject
|
|||||||
* A simple [Fragment] subclass as the second destination in the navigation.
|
* A simple [Fragment] subclass as the second destination in the navigation.
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class WidgetManagerFragment : Fragment(), WidgetOptionsDialogFragment.WidgetOptionsListener {
|
class WidgetManagerFragment : Fragment(),
|
||||||
|
WidgetOptionsDialogFragment.WidgetOptionsListener {
|
||||||
|
|
||||||
private var _binding: FragmentWidgetManagerBinding? = null
|
private var _binding: FragmentWidgetManagerBinding? = null
|
||||||
|
|
||||||
@@ -78,47 +79,51 @@ class WidgetManagerFragment : Fragment(), WidgetOptionsDialogFragment.WidgetOpti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the ActivityResultLaunchers
|
// Initialize the ActivityResultLaunchers
|
||||||
pickWidgetLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
pickWidgetLauncher =
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
val data = result.data
|
if (result.resultCode == Activity.RESULT_OK) {
|
||||||
data?.let {
|
val data = result.data
|
||||||
val appWidgetId = it.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
data?.let {
|
||||||
if (appWidgetId != -1) {
|
val appWidgetId = it.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
||||||
val appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId)
|
if (appWidgetId != -1) {
|
||||||
if (appWidgetInfo?.configure != null) {
|
val appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId)
|
||||||
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE)
|
if (appWidgetInfo?.configure != null) {
|
||||||
intent.component = appWidgetInfo.configure
|
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE)
|
||||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
intent.component = appWidgetInfo.configure
|
||||||
createWidgetLauncher.launch(intent)
|
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
|
||||||
} else {
|
createWidgetLauncher.launch(intent)
|
||||||
|
} else {
|
||||||
|
addWidget(appWidgetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (result.resultCode == Activity.RESULT_CANCELED) {
|
||||||
|
val appWidgetId =
|
||||||
|
result.data?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
||||||
|
if (appWidgetId != null && appWidgetId != -1) {
|
||||||
|
appWidgetHost.deleteAppWidgetId(appWidgetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createWidgetLauncher =
|
||||||
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
|
if (result.resultCode == Activity.RESULT_OK) {
|
||||||
|
val data = result.data
|
||||||
|
data?.let {
|
||||||
|
val appWidgetId = it.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
||||||
|
if (appWidgetId != -1) {
|
||||||
addWidget(appWidgetId)
|
addWidget(appWidgetId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (result.resultCode == Activity.RESULT_CANCELED) {
|
||||||
} else if (result.resultCode == Activity.RESULT_CANCELED) {
|
val appWidgetId =
|
||||||
val appWidgetId = result.data?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
result.data?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
||||||
if (appWidgetId != null && appWidgetId != -1) {
|
if (appWidgetId != null && appWidgetId != -1) {
|
||||||
appWidgetHost.deleteAppWidgetId(appWidgetId)
|
appWidgetHost.deleteAppWidgetId(appWidgetId)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createWidgetLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
|
||||||
val data = result.data
|
|
||||||
data?.let {
|
|
||||||
val appWidgetId = it.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
|
||||||
if (appWidgetId != -1) {
|
|
||||||
addWidget(appWidgetId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (result.resultCode == Activity.RESULT_CANCELED) {
|
|
||||||
val appWidgetId = result.data?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
|
|
||||||
if (appWidgetId != null && appWidgetId != -1) {
|
|
||||||
appWidgetHost.deleteAppWidgetId(appWidgetId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Set long-click listener on the root view
|
// Set long-click listener on the root view
|
||||||
binding.widgetParent.setOnLongClickListener {
|
binding.widgetParent.setOnLongClickListener {
|
||||||
@@ -161,7 +166,8 @@ class WidgetManagerFragment : Fragment(), WidgetOptionsDialogFragment.WidgetOpti
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun saveWidgetIds(widgetIds: List<Int>) {
|
private fun saveWidgetIds(widgetIds: List<Int>) {
|
||||||
val sharedPreferences = requireContext().getSharedPreferences(Constants.WIDGETS_PREFS, Activity.MODE_PRIVATE)
|
val sharedPreferences =
|
||||||
|
requireContext().getSharedPreferences(Constants.WIDGETS_PREFS, Activity.MODE_PRIVATE)
|
||||||
val editor = sharedPreferences.edit()
|
val editor = sharedPreferences.edit()
|
||||||
val widgetIdsSet = widgetIds.map { it.toString() }.toSet()
|
val widgetIdsSet = widgetIds.map { it.toString() }.toSet()
|
||||||
editor.putStringSet(Constants.APP_WIDGETS_ID, widgetIdsSet)
|
editor.putStringSet(Constants.APP_WIDGETS_ID, widgetIdsSet)
|
||||||
@@ -169,7 +175,8 @@ class WidgetManagerFragment : Fragment(), WidgetOptionsDialogFragment.WidgetOpti
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadWidgetIds(): List<Int> {
|
private fun loadWidgetIds(): List<Int> {
|
||||||
val sharedPreferences = requireContext().getSharedPreferences(Constants.WIDGETS_PREFS, Activity.MODE_PRIVATE)
|
val sharedPreferences =
|
||||||
|
requireContext().getSharedPreferences(Constants.WIDGETS_PREFS, Activity.MODE_PRIVATE)
|
||||||
val widgetIdsSet = sharedPreferences.getStringSet(Constants.APP_WIDGETS_ID, emptySet())
|
val widgetIdsSet = sharedPreferences.getStringSet(Constants.APP_WIDGETS_ID, emptySet())
|
||||||
return widgetIdsSet?.map { it.toInt() } ?: emptyList()
|
return widgetIdsSet?.map { it.toInt() } ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
package com.github.droidworksstudio.launcher.ui.widgetmanager
|
package com.github.droidworksstudio.launcher.ui.widgetmanager
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.widget.Button
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import com.github.droidworksstudio.launcher.Constants
|
import com.github.droidworksstudio.launcher.Constants
|
||||||
import com.github.droidworksstudio.launcher.R
|
|
||||||
|
|
||||||
class WidgetOptionsDialogFragment : DialogFragment() {
|
class WidgetOptionsDialogFragment : DialogFragment() {
|
||||||
|
|
||||||
@@ -18,7 +14,8 @@ class WidgetOptionsDialogFragment : DialogFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val appWidgetId = arguments?.getInt(ARG_APP_WIDGET_ID) ?: return super.onCreateDialog(savedInstanceState)
|
val appWidgetId =
|
||||||
|
arguments?.getInt(ARG_APP_WIDGET_ID) ?: return super.onCreateDialog(savedInstanceState)
|
||||||
|
|
||||||
val builder = AlertDialog.Builder(requireContext())
|
val builder = AlertDialog.Builder(requireContext())
|
||||||
builder.setTitle("Widget Options")
|
builder.setTitle("Widget Options")
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import androidx.core.widget.NestedScrollView
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
||||||
|
|
||||||
class GestureNestedScrollView(context: Context, attrs: AttributeSet) : NestedScrollView(context, attrs){
|
class GestureNestedScrollView(context: Context, attrs: AttributeSet) :
|
||||||
|
NestedScrollView(context, attrs) {
|
||||||
|
|
||||||
var scrollEventListener: ScrollEventListener? = null
|
var scrollEventListener: ScrollEventListener? = null
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.activities.SettingsActivity">
|
|
||||||
|
|
||||||
<include layout="@layout/content_settings"/>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
|
||||||
android:id="@+id/nav_host_fragment_content_settings"
|
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:navGraph="@navigation/nav_graph" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -7,6 +7,13 @@
|
|||||||
android:id="@+id/draw_background"
|
android:id="@+id/draw_background"
|
||||||
tools:context=".ui.drawer.DrawFragment">
|
tools:context=".ui.drawer.DrawFragment">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/touchArea"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:id="@+id/mainView"
|
android:id="@+id/mainView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -46,8 +53,9 @@
|
|||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/drawAdapter"
|
android:id="@+id/drawAdapter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/search_view_text" />
|
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@
|
|||||||
android:id="@+id/favorite_view"
|
android:id="@+id/favorite_view"
|
||||||
tools:context=".ui.favorite.FavoriteFragment">
|
tools:context=".ui.favorite.FavoriteFragment">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/touchArea"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/fragment_container"
|
android:id="@+id/fragment_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -22,7 +29,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="20dp"
|
android:layout_margin="20dp"
|
||||||
android:text="Home App Order"
|
android:text="@string/favorite_fragment_name"
|
||||||
android:textSize="@dimen/text_super_large"
|
android:textSize="@dimen/text_super_large"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@@ -31,11 +38,11 @@
|
|||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/favoriteAdapter"
|
android:id="@+id/favoriteAdapter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginHorizontal="20dp"
|
android:layout_marginHorizontal="20dp"
|
||||||
android:layout_marginTop="92dp"
|
android:layout_marginTop="92dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/topTextView" />
|
app:layout_constraintTop_toBottomOf="@id/topTextView" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -7,6 +7,13 @@
|
|||||||
android:id="@+id/hidden_view"
|
android:id="@+id/hidden_view"
|
||||||
tools:context=".ui.hidden.HiddenFragment">
|
tools:context=".ui.hidden.HiddenFragment">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/touchArea"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/fragment_container"
|
android:id="@+id/fragment_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -22,7 +29,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="20dp"
|
android:layout_margin="20dp"
|
||||||
android:text="Hidden App"
|
android:text="@string/hidden_fragment_name"
|
||||||
android:textSize="@dimen/text_super_large"
|
android:textSize="@dimen/text_super_large"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@@ -30,9 +37,8 @@
|
|||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/hiddenAdapter"
|
android:id="@+id/hiddenAdapter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginHorizontal="20dp"
|
android:layout_marginHorizontal="20dp"
|
||||||
android:layout_marginTop="92dp"
|
android:layout_marginTop="92dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/topTextView" />
|
app:layout_constraintTop_toBottomOf="@id/topTextView" />
|
||||||
|
|||||||
@@ -2,14 +2,24 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/mainLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:orientation="vertical"
|
||||||
tools:context=".ui.home.HomeFragment">
|
tools:context=".ui.home.HomeFragment">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/touchArea"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<com.github.droidworksstudio.launcher.view.GestureNestedScrollView
|
<com.github.droidworksstudio.launcher.view.GestureNestedScrollView
|
||||||
android:id="@+id/nestScrollView"
|
android:id="@+id/nestScrollView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:fillViewport="true"
|
android:fillViewport="true"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
@@ -81,7 +91,7 @@
|
|||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/appListAdapter"
|
android:id="@+id/appListAdapter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|||||||
@@ -6,9 +6,16 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.settings.SettingsFragment">
|
tools:context=".ui.settings.SettingsFragment">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/touchArea"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<com.github.droidworksstudio.launcher.view.GestureNestedScrollView
|
<com.github.droidworksstudio.launcher.view.GestureNestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/nestScrollView"
|
android:id="@+id/nestScrollView"
|
||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
|||||||
@@ -6,6 +6,13 @@
|
|||||||
android:id="@+id/draw_background"
|
android:id="@+id/draw_background"
|
||||||
tools:context=".ui.widgetmanager.WidgetManagerFragment">
|
tools:context=".ui.widgetmanager.WidgetManagerFragment">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/touchArea"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/widget_parent"
|
android:id="@+id/widget_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -21,13 +28,4 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp" />
|
android:padding="16dp" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/touchArea"
|
|
||||||
android:layout_marginTop="20dp"
|
|
||||||
android:layout_marginBottom="20dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -10,6 +10,10 @@
|
|||||||
<string name="settings_fragment_label">Settings Fragment</string>
|
<string name="settings_fragment_label">Settings Fragment</string>
|
||||||
<string name="widgets_fragment_label">Widgets Fragment</string>
|
<string name="widgets_fragment_label">Widgets Fragment</string>
|
||||||
|
|
||||||
|
<!-- Strings used for fragments header labels -->
|
||||||
|
<string name="favorite_fragment_name">Favorite Apps</string>
|
||||||
|
<string name="hidden_fragment_name">Hidden Apps</string>
|
||||||
|
|
||||||
<string name="battery_level">%s%%</string>
|
<string name="battery_level">%s%%</string>
|
||||||
<string name="search">Search</string>
|
<string name="search">Search</string>
|
||||||
|
|
||||||
@@ -26,7 +30,6 @@
|
|||||||
|
|
||||||
<string name="settings_name">Launcher Settings</string>
|
<string name="settings_name">Launcher Settings</string>
|
||||||
<string name="settings_version">%s Version: %s</string>
|
<string name="settings_version">%s Version: %s</string>
|
||||||
<string name="settings_home">Home</string>
|
|
||||||
|
|
||||||
<string name="settings_title_home_display_preferences">Display</string>
|
<string name="settings_title_home_display_preferences">Display</string>
|
||||||
<string name="settings_title_home_behavior_preferences">Behavior</string>
|
<string name="settings_title_home_behavior_preferences">Behavior</string>
|
||||||
@@ -101,6 +104,7 @@
|
|||||||
<string name="accessibility_settings_enable">Enable</string>
|
<string name="accessibility_settings_enable">Enable</string>
|
||||||
<string name="accessibility_settings_disable">Disable</string>
|
<string name="accessibility_settings_disable">Disable</string>
|
||||||
|
|
||||||
|
<string name="accessibility_service_name">Easy Launcher Actions Service</string>
|
||||||
<string name="accessibility_service_desc">Please turn on accessibility service to use double tap to lock feature in Easy Launcher.\n\nThis permission is used only to turn off your screen.Our accessibility service does not collect or share any data.</string>
|
<string name="accessibility_service_desc">Please turn on accessibility service to use double tap to lock feature in Easy Launcher.\n\nThis permission is used only to turn off your screen.Our accessibility service does not collect or share any data.</string>
|
||||||
<string name="admin_permission_message">Easy launcher promises to use lock screen permission responsibly. Easy launcher does not collect or share any data.</string>
|
<string name="admin_permission_message">Easy launcher promises to use lock screen permission responsibly. Easy launcher does not collect or share any data.</string>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user