diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a2a636bb..8b3f79da 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -120,6 +120,9 @@ dependencies {
}
implementation(dependencyNotation = libs.androidx.constraintlayout.compose)
+ implementation(dependencyNotation = libs.glance)
+ implementation(dependencyNotation = libs.glance.appwidget)
+ implementation(dependencyNotation = libs.glance.material3)
// Image Compression
implementation(dependencyNotation = libs.compressor)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2744a429..8c6db43d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -201,5 +201,15 @@
android:value="eu_consent_policy" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/auto/AutoCleanScheduler.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/auto/AutoCleanScheduler.kt
index 24b43155..3c28b1a6 100644
--- a/app/src/main/kotlin/com/d4rk/cleaner/app/auto/AutoCleanScheduler.kt
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/auto/AutoCleanScheduler.kt
@@ -4,6 +4,7 @@ import android.content.Context
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.d4rk.cleaner.core.data.datastore.DataStore
import kotlinx.coroutines.runBlocking
@@ -32,4 +33,10 @@ object AutoCleanScheduler {
fun cancel(context: Context) {
WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME)
}
+
+ fun runOnce(context: Context) {
+ val request = OneTimeWorkRequestBuilder()
+ .build()
+ WorkManager.getInstance(context).enqueue(request)
+ }
}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/settings/cleaning/ui/CleaningSettingsList.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/settings/cleaning/ui/CleaningSettingsList.kt
index b4fa0aed..d1e555c0 100644
--- a/app/src/main/kotlin/com/d4rk/cleaner/app/settings/cleaning/ui/CleaningSettingsList.kt
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/settings/cleaning/ui/CleaningSettingsList.kt
@@ -49,6 +49,7 @@ fun CleaningSettingsList(paddingValues : PaddingValues) {
val streakReminderEnabled: Boolean by dataStore.streakReminderEnabled.collectAsState(initial = false)
val showStreakCardPref: Boolean by dataStore.showStreakCard.collectAsState(initial = true)
val autoCleanEnabled: Boolean by dataStore.autoCleanEnabled.collectAsState(initial = false)
+ val widgetActionsEnabled: Boolean by dataStore.widgetActionsEnabled.collectAsState(initial = true)
LazyColumn(
modifier = Modifier
@@ -307,5 +308,25 @@ fun CleaningSettingsList(paddingValues : PaddingValues) {
}
}
}
+
+ item {
+ PreferenceCategoryItem(title = stringResource(id = R.string.widget_settings_title))
+ SmallVerticalSpacer()
+
+ Column(
+ modifier = Modifier
+ .padding(horizontal = SizeConstants.LargeSize)
+ .clip(shape = RoundedCornerShape(size = SizeConstants.LargeSize))
+ ) {
+ SwitchPreferenceItem(
+ title = stringResource(id = R.string.enable_widget_actions),
+ checked = widgetActionsEnabled,
+ ) { isChecked ->
+ CoroutineScope(Dispatchers.IO).launch {
+ dataStore.saveWidgetActionsEnabled(isChecked)
+ }
+ }
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/CleanerWidgetReceiver.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/CleanerWidgetReceiver.kt
new file mode 100644
index 00000000..49c695ff
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/CleanerWidgetReceiver.kt
@@ -0,0 +1,85 @@
+package com.d4rk.cleaner.app.widgets
+
+import android.content.Context
+import android.content.Intent
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.unit.dp
+import androidx.glance.GlanceId
+import androidx.glance.GlanceModifier
+import androidx.glance.Image
+import androidx.glance.ImageProvider
+import androidx.glance.action.clickable
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.GlanceAppWidgetReceiver
+import androidx.glance.appwidget.action.ActionCallback
+import androidx.glance.appwidget.action.ActionParameters
+import androidx.glance.appwidget.action.actionRunCallback
+import androidx.glance.appwidget.provideContent
+import androidx.glance.layout.Alignment
+import androidx.glance.layout.Row
+import androidx.glance.layout.Spacer
+import androidx.glance.layout.fillMaxWidth
+import androidx.glance.layout.padding
+import androidx.glance.layout.width
+import com.d4rk.cleaner.R
+import com.d4rk.cleaner.app.auto.AutoCleanScheduler
+import com.d4rk.cleaner.app.main.ui.MainActivity
+import com.d4rk.cleaner.core.data.datastore.DataStore
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.runBlocking
+
+class CleanerWidgetReceiver : GlanceAppWidgetReceiver() {
+ override val glanceAppWidget: GlanceAppWidget = CleanerWidget()
+}
+
+class CleanerWidget : GlanceAppWidget() {
+ override suspend fun provideGlance(context: Context, id: GlanceId) {
+ provideContent { WidgetContent() }
+ }
+
+ @Composable
+ private fun WidgetContent() {
+ Row(
+ modifier = GlanceModifier.fillMaxWidth().padding(8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Image(
+ provider = ImageProvider(R.drawable.ic_folder_search),
+ contentDescription = "scan",
+ modifier = GlanceModifier.clickable(actionRunCallback())
+ )
+ Spacer(modifier = GlanceModifier.width(16.dp))
+ Image(
+ provider = ImageProvider(R.drawable.ic_auto_fix_high),
+ contentDescription = "clean",
+ modifier = GlanceModifier.clickable(actionRunCallback())
+ )
+ }
+ }
+}
+
+class OpenScanAction : ActionCallback {
+ override suspend fun onAction(context: Context, glanceId: GlanceId, parameters: ActionParameters) {
+ if (context.isWidgetActionsEnabled()) {
+ val intent = Intent(context, MainActivity::class.java).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ putExtra("open_scan", true)
+ }
+ context.startActivity(intent)
+ }
+ }
+}
+
+class RunCleanAction : ActionCallback {
+ override suspend fun onAction(context: Context, glanceId: GlanceId, parameters: ActionParameters) {
+ if (context.isWidgetActionsEnabled()) {
+ AutoCleanScheduler.runOnce(context)
+ }
+ }
+}
+
+private fun Context.isWidgetActionsEnabled(): Boolean {
+ val ds = DataStore(this)
+ return runBlocking { ds.widgetActionsEnabled.first() }
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/StorageWidgetReceiver.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/StorageWidgetReceiver.kt
new file mode 100644
index 00000000..ffbe3565
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/StorageWidgetReceiver.kt
@@ -0,0 +1,9 @@
+package com.d4rk.cleaner.app.widgets
+
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.GlanceAppWidgetReceiver
+import com.d4rk.cleaner.app.widgets.ui.StorageStatsWidget
+
+class StorageWidgetReceiver : GlanceAppWidgetReceiver() {
+ override val glanceAppWidget: GlanceAppWidget = StorageStatsWidget()
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/data/StorageStatsRepository.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/data/StorageStatsRepository.kt
new file mode 100644
index 00000000..aef43177
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/data/StorageStatsRepository.kt
@@ -0,0 +1,11 @@
+package com.d4rk.cleaner.app.widgets.data
+
+import android.app.Application
+import com.d4rk.cleaner.app.clean.memory.data.MemoryRepositoryImpl
+import com.d4rk.cleaner.app.clean.memory.domain.data.model.StorageInfo
+
+class StorageStatsRepository(private val application: Application) {
+ suspend fun getStorageInfo(): StorageInfo {
+ return MemoryRepositoryImpl(application).getStorageInfo()
+ }
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/OpenScanAction.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/OpenScanAction.kt
new file mode 100644
index 00000000..2cb6762d
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/OpenScanAction.kt
@@ -0,0 +1,21 @@
+package com.d4rk.cleaner.app.widgets.domain.actions
+
+import android.content.Context
+import android.content.Intent
+import androidx.glance.GlanceId
+import androidx.glance.action.ActionParameters
+import androidx.glance.appwidget.action.ActionCallback
+import com.d4rk.cleaner.app.main.ui.MainActivity
+import com.d4rk.cleaner.app.widgets.domain.actions.isWidgetActionsEnabled
+
+class OpenScanAction : ActionCallback {
+ override suspend fun onAction(context: Context, glanceId: androidx.glance.GlanceId, parameters: ActionParameters) {
+ if (context.isWidgetActionsEnabled()) {
+ val intent = Intent(context, MainActivity::class.java).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ putExtra("open_scan", true)
+ }
+ context.startActivity(intent)
+ }
+ }
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/RunCleanAction.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/RunCleanAction.kt
new file mode 100644
index 00000000..5522b3ae
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/RunCleanAction.kt
@@ -0,0 +1,16 @@
+package com.d4rk.cleaner.app.widgets.domain.actions
+
+import android.content.Context
+import androidx.glance.GlanceId
+import androidx.glance.action.ActionParameters
+import androidx.glance.appwidget.action.ActionCallback
+import com.d4rk.cleaner.app.auto.AutoCleanScheduler
+import com.d4rk.cleaner.app.widgets.domain.actions.isWidgetActionsEnabled
+
+class RunCleanAction : ActionCallback {
+ override suspend fun onAction(context: Context, glanceId: GlanceId, parameters: ActionParameters) {
+ if (context.isWidgetActionsEnabled()) {
+ AutoCleanScheduler.runOnce(context)
+ }
+ }
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/WidgetActions.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/WidgetActions.kt
new file mode 100644
index 00000000..26249c97
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/domain/actions/WidgetActions.kt
@@ -0,0 +1,18 @@
+package com.d4rk.cleaner.app.widgets.domain.actions
+
+import android.content.Context
+import androidx.glance.GlanceModifier
+import androidx.glance.action.clickable
+import androidx.glance.appwidget.action.actionRunCallback
+import com.d4rk.cleaner.core.data.datastore.DataStore
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.runBlocking
+
+internal fun Context.isWidgetActionsEnabled(): Boolean {
+ val ds = DataStore(this)
+ return runBlocking { ds.widgetActionsEnabled.first() }
+}
+
+internal fun GlanceModifier.scanAction() = clickable(actionRunCallback())
+
+internal fun GlanceModifier.cleanAction() = clickable(actionRunCallback())
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/ui/StorageStatsWidget.kt b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/ui/StorageStatsWidget.kt
new file mode 100644
index 00000000..39054be2
--- /dev/null
+++ b/app/src/main/kotlin/com/d4rk/cleaner/app/widgets/ui/StorageStatsWidget.kt
@@ -0,0 +1,185 @@
+package com.d4rk.cleaner.app.widgets.ui
+
+import android.app.Application
+import android.content.Context
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.glance.GlanceId
+import androidx.glance.GlanceModifier
+import androidx.glance.Image
+import androidx.glance.ImageProvider
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.LinearProgressIndicator
+import androidx.glance.appwidget.SizeMode
+import androidx.glance.appwidget.provideContent
+import androidx.glance.color.ColorProvider
+import androidx.glance.layout.Alignment
+import androidx.glance.layout.Box
+import androidx.glance.layout.Column
+import androidx.glance.layout.Row
+import androidx.glance.layout.Spacer
+import androidx.glance.layout.fillMaxSize
+import androidx.glance.layout.fillMaxWidth
+import androidx.glance.layout.height
+import androidx.glance.layout.padding
+import androidx.glance.layout.width
+import androidx.glance.text.FontWeight
+import androidx.glance.text.Text
+import androidx.glance.text.TextStyle
+import com.d4rk.cleaner.R
+import com.d4rk.cleaner.app.clean.memory.domain.data.model.StorageInfo
+import com.d4rk.cleaner.app.widgets.data.StorageStatsRepository
+import com.d4rk.cleaner.app.widgets.domain.actions.cleanAction
+import com.d4rk.cleaner.app.widgets.domain.actions.scanAction
+import com.d4rk.cleaner.core.utils.helpers.FileSizeFormatter
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+
+
+class StorageStatsWidget : GlanceAppWidget(errorUiLayout = R.layout.widget_error) {
+
+ override val sizeMode = SizeMode.Exact
+
+ override suspend fun provideGlance(context: Context, id: GlanceId) {
+ val repository = StorageStatsRepository(context.applicationContext as Application)
+ val info = withContext(Dispatchers.IO) { repository.getStorageInfo() }
+ provideContent { StorageStatsContent(info) }
+ }
+}
+
+@Composable
+private fun StorageStatsContent(storageInfo: StorageInfo) {
+
+ val storageColorProvider = ColorProvider(day = Color(0xFF2196F3), night = Color(0xFF90CAF9)) // Blue
+ val progressBarBackgroundColorProvider = ColorProvider(day = Color(0xFFE3F2FD), night = Color(0xFF1A237E)) // Light blue / Dark blue
+ val primaryTextColor = ColorProvider(day = Color(0xFFFFFFFF), night = Color(0xFF212121)) // White / Dark text
+ val widgetSurfaceVariantColor = ColorProvider(day = Color(0xFF757575), night = Color(0xFFBDBDBD)) // Grey
+
+ val widgetTitleColorProvider = widgetSurfaceVariantColor
+ val widgetContentColorProvider = progressBarBackgroundColorProvider
+
+ Column(
+ modifier = GlanceModifier
+ .fillMaxSize()
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Row(
+ modifier = GlanceModifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Image(
+ provider = ImageProvider(R.drawable.ic_voice_selection),
+ contentDescription = stringResource(id = R.string.storage_information),
+ modifier = GlanceModifier.padding(end = 8.dp)
+ )
+ Text(
+ text = stringResource(id = R.string.widget_storage_title),
+ style = TextStyle(
+ fontWeight = FontWeight.Bold,
+ fontSize = 18.sp,
+ color = widgetTitleColorProvider
+ )
+ )
+ }
+
+ Spacer(modifier = GlanceModifier.height(8.dp))
+
+ Box(modifier = GlanceModifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
+ val progress = if (storageInfo.storageUsageProgress == 0f) 0f else storageInfo.usedStorage.toFloat() / storageInfo.storageUsageProgress
+ LinearProgressIndicator(
+ progress = progress,
+ modifier = GlanceModifier.fillMaxWidth().height(10.dp),
+ color = storageColorProvider,
+ backgroundColor = widgetContentColorProvider
+ )
+ Text(
+ text = "${(progress * 100).toInt()}% ${stringResource(id = R.string.used)}",
+ style = TextStyle(
+ fontSize = 12.sp,
+ fontWeight = FontWeight.Medium,
+ color = primaryTextColor
+ ),
+ modifier = GlanceModifier.padding(horizontal = 4.dp)
+ )
+ }
+
+ Spacer(modifier = GlanceModifier.height(12.dp))
+
+ Row(
+ modifier = GlanceModifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ StorageDetailItem(stringResource(id = R.string.used), FileSizeFormatter.format(storageInfo.usedStorage))
+ Spacer(modifier = GlanceModifier.width(16.dp))
+ StorageDetailItem(stringResource(id = R.string.free), FileSizeFormatter.format(storageInfo.freeStorage))
+ Spacer(modifier = GlanceModifier.width(16.dp))
+ StorageDetailItem(stringResource(id = R.string.total), FileSizeFormatter.format(storageInfo.storageUsageProgress.toLong()))
+ }
+
+ Spacer(modifier = GlanceModifier.height(16.dp))
+
+ Row(
+ modifier = GlanceModifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ ActionButton(
+ text = stringResource(id = R.string.widget_clean_up),
+ action = GlanceModifier.cleanAction(),
+ icon = R.drawable.ic_person_pin
+ )
+ Spacer(modifier = GlanceModifier.width(16.dp))
+ ActionButton(
+ text = stringResource(id = R.string.scan_now),
+ action = GlanceModifier.scanAction(),
+ icon = R.drawable.ic_folder_search
+ )
+ }
+ }
+}
+
+@Composable
+private fun StorageDetailItem(label: String, value: String) {
+ val labelColor = ColorProvider(day = Color(0xFF757575), night = Color(0xFFBDBDBD))
+ val valueColor = ColorProvider(day = Color(0xFF212121), night = Color(0xFFFFFFFF))
+ Column(horizontalAlignment = Alignment.CenterHorizontally) {
+ Text(
+ text = label,
+ style = TextStyle(fontSize = 12.sp, color = labelColor)
+ )
+ Text(
+ text = value,
+ style = TextStyle(fontSize = 14.sp, fontWeight = FontWeight.Medium, color = valueColor)
+ )
+ }
+}
+
+@Composable
+private fun ActionButton(text: String, action: GlanceModifier, icon: Int) {
+ val textColor = ColorProvider(day = Color(0xFF2196F3), night = Color(0xFF90CAF9))
+
+ Row(
+
+ modifier = action.padding(vertical = 8.dp, horizontal = 12.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Image(
+ provider = ImageProvider(icon),
+ contentDescription = text,
+ modifier = GlanceModifier.padding(end = 6.dp)
+ )
+ Text(
+ text = text,
+ style = TextStyle(
+ fontSize = 14.sp,
+ fontWeight = FontWeight.Medium,
+ color = textColor
+ )
+ )
+ }
+}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/core/data/datastore/DataStore.kt b/app/src/main/kotlin/com/d4rk/cleaner/core/data/datastore/DataStore.kt
index 6bd13503..64b92d51 100644
--- a/app/src/main/kotlin/com/d4rk/cleaner/core/data/datastore/DataStore.kt
+++ b/app/src/main/kotlin/com/d4rk/cleaner/core/data/datastore/DataStore.kt
@@ -400,4 +400,14 @@ class DataStore(val context : Context) : CommonDataStore(context = context) {
}
}
+ private val widgetActionsEnabledKey = booleanPreferencesKey(AppDataStoreConstants.DATA_STORE_WIDGET_ACTIONS_ENABLED)
+ val widgetActionsEnabled: Flow = dataStore.data.map { prefs ->
+ prefs[widgetActionsEnabledKey] ?: true
+ }
+
+ suspend fun saveWidgetActionsEnabled(enabled: Boolean) {
+ dataStore.edit { prefs ->
+ prefs[widgetActionsEnabledKey] = enabled
+ }
+ }
}
diff --git a/app/src/main/kotlin/com/d4rk/cleaner/core/utils/constants/datastore/AppDataStoreConstants.kt b/app/src/main/kotlin/com/d4rk/cleaner/core/utils/constants/datastore/AppDataStoreConstants.kt
index efd858a6..b0712472 100644
--- a/app/src/main/kotlin/com/d4rk/cleaner/core/utils/constants/datastore/AppDataStoreConstants.kt
+++ b/app/src/main/kotlin/com/d4rk/cleaner/core/utils/constants/datastore/AppDataStoreConstants.kt
@@ -38,4 +38,5 @@ object AppDataStoreConstants : DataStoreNamesConstants() {
const val DATA_STORE_STREAK_HIDE_UNTIL = "streak_hide_until"
const val DATA_STORE_AUTO_CLEAN_ENABLED = "auto_clean_enabled"
const val DATA_STORE_AUTO_CLEAN_FREQUENCY_DAYS = "auto_clean_frequency_days"
+ const val DATA_STORE_WIDGET_ACTIONS_ENABLED = "widget_actions_enabled"
}
diff --git a/app/src/main/res/layout/widget_error.xml b/app/src/main/res/layout/widget_error.xml
new file mode 100644
index 00000000..80d8ae37
--- /dev/null
+++ b/app/src/main/res/layout/widget_error.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/values-ar-rEG/strings.xml b/app/src/main/res/values-ar-rEG/strings.xml
index c7814bc0..e4b6602e 100644
--- a/app/src/main/res/values-ar-rEG/strings.xml
+++ b/app/src/main/res/values-ar-rEG/strings.xml
@@ -308,6 +308,14 @@
التنظيف التلقائي
تمكين التنظيف التلقائي
+ أداة الشاشة الرئيسية
+ تمكين إجراءات الأداة
+ نظرة على التخزين
+ المستخدم
+ المتاح
+ الإجمالي
+ تنظيف
+ Can\'t display widget content
طلب حذف الحزم [REQUEST_DELETE_PACKAGES]
بيسمح للتطبيق يطلب حذف الحزم. ده ممكن يستخدم لإلغاء تثبيت تطبيقات تانية من الجهاز.
diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml
index 773accf0..a7ca7000 100644
--- a/app/src/main/res/values-bg-rBG/strings.xml
+++ b/app/src/main/res/values-bg-rBG/strings.xml
@@ -283,6 +283,14 @@
Автоматично почистване
Активирайте автоматичното почистване
+ Уиджет за началния екран
+ Разреши действия на уиджета
+ Статистика за паметта
+ Използвано
+ Свободно
+ Общо
+ Почистване
+ Can\'t display widget content
Заявка за изтриване на пакети [REQUEST_DELETE_PACKAGES]
Позволява на приложението да изисква изтриването на пакети. Това може да се използва за деинсталиране на други приложения от устройството.
diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml
index a282a618..05f38779 100644
--- a/app/src/main/res/values-bn-rBD/strings.xml
+++ b/app/src/main/res/values-bn-rBD/strings.xml
@@ -283,6 +283,14 @@
স্বয়ংক্রিয় ক্লিনআপ
স্বয়ংক্রিয় পরিষ্কার সক্ষম করুন
+ হোম স্ক্রিন উইজেট
+ উইজেট অ্যাকশন সক্রিয় করুন
+ স্টোরেজ পরিসংখ্যান
+ ব্যবহৃত
+ ফাঁকা
+ মোট
+ পরিষ্কার করুন
+ Can\'t display widget content
প্যাকেজ মোছার অনুরোধ [REQUEST_DELETE_PACKAGES]
অ্যাপটিকে প্যাকেজ মোছার অনুরোধ করার অনুমতি দেয়। এটি ডিভাইস থেকে অন্যান্য অ্যাপ আনইনস্টল করতে ব্যবহার করা যেতে পারে
diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml
index cddfde08..3ac4d953 100644
--- a/app/src/main/res/values-de-rDE/strings.xml
+++ b/app/src/main/res/values-de-rDE/strings.xml
@@ -284,6 +284,14 @@
Automatische Aufräumarbeiten
Aktivieren Sie die automatische Reinigung
+ Startbildschirm-Widget
+ Widget-Aktionen aktivieren
+ Speicherinfo
+ Belegt
+ Frei
+ Gesamt
+ Bereinigen
+ Can\'t display widget content
Löschen von Paketen anfordern [REQUEST_DELETE_PACKAGES]
Ermöglicht der App, das Löschen von Paketen anzufordern. Dies kann verwendet werden, um andere Apps vom Gerät zu deinstallieren
diff --git a/app/src/main/res/values-es-rGQ/strings.xml b/app/src/main/res/values-es-rGQ/strings.xml
index efd2b403..f32be7e3 100644
--- a/app/src/main/res/values-es-rGQ/strings.xml
+++ b/app/src/main/res/values-es-rGQ/strings.xml
@@ -290,6 +290,14 @@
Limpieza automática
Habilitar la limpieza automática
+ Widget de inicio
+ Habilitar acciones del widget
+ Información de almacenamiento
+ Usado
+ Libre
+ Total
+ Limpiar
+ Can\'t display widget content
Solicitar eliminación de paquetes [REQUEST_DELETE_PACKAGES]
Permite que la app solicite la eliminación de paquetes. Esto se puede usar para desinstalar otras apps del dispositivo.
diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml
index cd1d5f23..14cae30a 100644
--- a/app/src/main/res/values-es-rMX/strings.xml
+++ b/app/src/main/res/values-es-rMX/strings.xml
@@ -290,6 +290,14 @@
Limpieza automática
Habilitar la limpieza automática
+ Widget de inicio
+ Habilitar acciones del widget
+ Información de almacenamiento
+ Usado
+ Libre
+ Total
+ Limpiar
+ Can\'t display widget content
Solicitar eliminación de paquetes [REQUEST_DELETE_PACKAGES]
Permite que la aplicación solicite la eliminación de paquetes. Esto se puede usar para desinstalar otras aplicaciones del dispositivo.
diff --git a/app/src/main/res/values-fil-rPH/strings.xml b/app/src/main/res/values-fil-rPH/strings.xml
index 25803e3a..d4cbcf78 100644
--- a/app/src/main/res/values-fil-rPH/strings.xml
+++ b/app/src/main/res/values-fil-rPH/strings.xml
@@ -284,6 +284,14 @@
Awtomatikong paglilinis
Paganahin ang awtomatikong paglilinis
+ Widget sa Home Screen
+ Paganahin ang mga aksyon ng widget
+ Impormasyon sa storage
+ Nagamit
+ Libre
+ Kabuuan
+ Linisin
+ Can\'t display widget content
Humiling ng pagbura ng mga package [REQUEST_DELETE_PACKAGES]
Pinapayagan ang app na humiling ng pagbura ng mga package. Maaari itong gamitin para i-uninstall ang iba pang mga app mula sa device
diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml
index 35192820..a251cdb3 100644
--- a/app/src/main/res/values-fr-rFR/strings.xml
+++ b/app/src/main/res/values-fr-rFR/strings.xml
@@ -291,6 +291,14 @@
Nettoyage automatique
Activer le nettoyage automatique
+ Widget d\'écran d\'accueil
+ Activer les actions du widget
+ Aperçu du stockage
+ Utilisé
+ Libre
+ Total
+ Nettoyer
+ Can\'t display widget content
Demander la suppression de paquets [REQUEST_DELETE_PACKAGES]
Permet à l\'application de demander la suppression de paquets. Peut être utilisé pour désinstaller d\'autres applications de l\'appareil.
diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml
index 69ab04dd..90234b3a 100644
--- a/app/src/main/res/values-hi-rIN/strings.xml
+++ b/app/src/main/res/values-hi-rIN/strings.xml
@@ -284,6 +284,14 @@
स्वत: सफाई
स्वचालित सफाई सक्षम करें
+ होम स्क्रीन विजेट
+ विजेट क्रियाएँ सक्षम करें
+ स्टोरेज जानकारी
+ उपयोग में
+ खाली
+ कुल
+ साफ करें
+ Can\'t display widget content
पैकेज हटाने का अनुरोध करें [REQUEST_DELETE_PACKAGES]
ऐप को पैकेज हटाने का अनुरोध करने की अनुमति देता है। इसका उपयोग डिवाइस से अन्य ऐप्स को अनइंस्टॉल करने के लिए किया जा सकता है
diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml
index 306c5c2c..45b764f3 100644
--- a/app/src/main/res/values-hu-rHU/strings.xml
+++ b/app/src/main/res/values-hu-rHU/strings.xml
@@ -284,6 +284,14 @@
Automatikus takarítás
Engedélyezze az automatikus tisztítást
+ Kezdőképernyő widget
+ Widget műveletek engedélyezése
+ Tárhely információ
+ Használt
+ Szabad
+ Összesen
+ Tisztítás
+ Can\'t display widget content
Csomagok törlésének kérése [REQUEST_DELETE_PACKAGES]
Lehetővé teszi az alkalmazás számára, hogy csomagok törlését kérje. Ezzel más alkalmazásokat is el lehet távolítani az eszközről
diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml
index bb7ac48a..6c754469 100644
--- a/app/src/main/res/values-in-rID/strings.xml
+++ b/app/src/main/res/values-in-rID/strings.xml
@@ -278,6 +278,14 @@
Pembersihan Otomatis
Aktifkan pembersihan otomatis
+ Widget Layar Utama
+ Aktifkan aksi widget
+ Informasi penyimpanan
+ Terpakai
+ Tersedia
+ Total
+ Bersihkan
+ Can\'t display widget content
Minta hapus paket [REQUEST_DELETE_PACKAGES]
Mengizinkan aplikasi untuk meminta penghapusan paket. Ini dapat digunakan untuk mencopot pemasangan aplikasi lain dari perangkat
diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml
index 26e0c13b..1fb507c4 100644
--- a/app/src/main/res/values-it-rIT/strings.xml
+++ b/app/src/main/res/values-it-rIT/strings.xml
@@ -290,6 +290,14 @@
Pulizia automatica
Abilita la pulizia automatica
+ Widget schermata Home
+ Abilita azioni widget
+ Statistiche di archiviazione
+ Usato
+ Libero
+ Totale
+ Pulizia
+ Can\'t display widget content
Richiedi eliminazione pacchetti [REQUEST_DELETE_PACKAGES]
Consente all\'app di richiedere l\'eliminazione di pacchetti. Può essere utilizzato per disinstallare altre app dal dispositivo
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index cd6d5699..39e5ca4c 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -278,6 +278,14 @@
自動クリーンアップ
自動クリーニングを有効にします
+ ホーム画面ウィジェット
+ ウィジェットの操作を有効にする
+ ストレージ概要
+ 使用済み
+ 空き
+ 合計
+ クリーンアップ
+ Can\'t display widget content
パッケージ削除のリクエスト [REQUEST_DELETE_PACKAGES]
アプリがパッケージの削除をリクエストできるようにします。これにより、デバイスから他のアプリをアンインストールできます
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index ecb66fa5..b2eaf061 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -278,6 +278,14 @@
자동 정리
자동 청소를 활성화합니다
+ 홈 화면 위젯
+ 위젯 동작 활성화
+ 저장소 정보
+ 사용됨
+ 여유
+ 전체
+ 정리하기
+ Can\'t display widget content
패키지 삭제 요청 [REQUEST_DELETE_PACKAGES]
앱이 패키지 삭제를 요청할 수 있도록 허용합니다. 이를 사용하여 기기에서 다른 앱을 제거할 수 있습니다.
diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml
index 1546b905..d3c555f2 100644
--- a/app/src/main/res/values-pl-rPL/strings.xml
+++ b/app/src/main/res/values-pl-rPL/strings.xml
@@ -296,6 +296,14 @@
Automatyczne czyszczenie
Włącz automatyczne czyszczenie
+ Widżet ekranu głównego
+ Włącz akcje widżetu
+ Informacje o pamięci
+ Użyte
+ Wolne
+ Razem
+ Wyczyść
+ Can\'t display widget content
Żądanie usunięcia pakietów [REQUEST_DELETE_PACKAGES]
Pozwala aplikacji żądać usunięcia pakietów. Może to być użyte do odinstalowania innych aplikacji z urządzenia
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 28073b5f..9edddddc 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -290,6 +290,14 @@
Limpeza automática
Ativar limpeza automática
+ Widget da tela inicial
+ Ativar ações do widget
+ Informações de armazenamento
+ Usado
+ Livre
+ Total
+ Limpar
+ Can\'t display widget content
Solicitar exclusão de pacotes [REQUEST_DELETE_PACKAGES]
Permite que o aplicativo solicite a exclusão de pacotes. Isso pode ser usado para desinstalar outros aplicativos do dispositivo
diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml
index cc510ace..72ee2c30 100644
--- a/app/src/main/res/values-ro-rRO/strings.xml
+++ b/app/src/main/res/values-ro-rRO/strings.xml
@@ -290,6 +290,14 @@
Curățare automată
Activați curățarea automată
+ Widget ecran principal
+ Activează acțiunile widgetului
+ Informații stocare
+ Folosit
+ Liber
+ Total
+ Curățare
+ Can\'t display widget content
Solicită ștergerea pachetelor [REQUEST_DELETE_PACKAGES]
Permite aplicației să solicite ștergerea pachetelor. Aceasta poate fi utilizată pentru a dezinstala alte aplicații de pe dispozitiv
diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml
index 64a5a1ff..bd11993f 100644
--- a/app/src/main/res/values-ru-rRU/strings.xml
+++ b/app/src/main/res/values-ru-rRU/strings.xml
@@ -296,6 +296,14 @@
Автоматическая очистка
Включить автоматическую очистку
+ Виджет главного экрана
+ Включить действия виджета
+ Состояние хранилища
+ Использовано
+ Свободно
+ Всего
+ Очистить
+ Can\'t display widget content
Запросить удаление пакетов [REQUEST_DELETE_PACKAGES]
Позволяет приложению запрашивать удаление пакетов. Это можно использовать для удаления других приложений с устройства
diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml
index 3b5a5c2e..83f1686a 100644
--- a/app/src/main/res/values-sv-rSE/strings.xml
+++ b/app/src/main/res/values-sv-rSE/strings.xml
@@ -284,6 +284,14 @@
Automatisk sanering
Aktivera automatisk rengöring
+ Startskärmswidget
+ Aktivera widgetåtgärder
+ Lagringsinformation
+ Använt
+ Ledigt
+ Totalt
+ Rensa
+ Can\'t display widget content
Begär radering av paket [REQUEST_DELETE_PACKAGES]
Tillåter appen att begära radering av paket. Detta kan användas för att avinstallera andra appar från enheten
diff --git a/app/src/main/res/values-th-rTH/strings.xml b/app/src/main/res/values-th-rTH/strings.xml
index 6474bd58..94598fce 100644
--- a/app/src/main/res/values-th-rTH/strings.xml
+++ b/app/src/main/res/values-th-rTH/strings.xml
@@ -278,6 +278,14 @@
การล้างข้อมูลอัตโนมัติ
เปิดใช้งานการทำความสะอาดอัตโนมัติ
+ วิดเจ็ตหน้าจอหลัก
+ เปิดใช้การทำงานของวิดเจ็ต
+ ข้อมูลการจัดเก็บ
+ ใช้ไป
+ ว่าง
+ รวม
+ ล้างข้อมูล
+ Can\'t display widget content
ร้องขอการลบแพ็คเกจ [REQUEST_DELETE_PACKAGES]
อนุญาตให้แอปสามารถร้องขอการลบแพ็คเกจได้ ซึ่งสามารถใช้เพื่อถอนการติดตั้งแอปอื่นๆ ออกจากอุปกรณ์
diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml
index 2e40ce31..13277f16 100644
--- a/app/src/main/res/values-tr-rTR/strings.xml
+++ b/app/src/main/res/values-tr-rTR/strings.xml
@@ -284,6 +284,14 @@
Otomatik temizlik
Otomatik temizliği etkinleştirin
+ Ana ekran widget\'i
+ Widget işlemlerini etkinleştir
+ Depolama bilgileri
+ Kullanılan
+ Boş
+ Toplam
+ Temizle
+ Can\'t display widget content
Paket silme isteği [REQUEST_DELETE_PACKAGES]
Uygulamanın paketlerin silinmesini istemesine izin verir. Bu, cihazdan diğer uygulamaları kaldırmak için kullanılabilir
diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml
index 05fcf8ca..70d374b4 100644
--- a/app/src/main/res/values-uk-rUA/strings.xml
+++ b/app/src/main/res/values-uk-rUA/strings.xml
@@ -296,6 +296,14 @@
Автоматичне очищення
Увімкнути автоматичне очищення
+ Віджет головного екрану
+ Увімкнути дії віджета
+ Інформація про сховище
+ Використано
+ Вільно
+ Всього
+ Очистити
+ Can\'t display widget content
Запит на видалення пакетів [REQUEST_DELETE_PACKAGES]
Дозволяє додатку запитувати видалення пакетів. Це може використовуватися для видалення інших додатків з пристрою
diff --git a/app/src/main/res/values-ur-rPK/strings.xml b/app/src/main/res/values-ur-rPK/strings.xml
index ece1e4b5..c8f6a370 100644
--- a/app/src/main/res/values-ur-rPK/strings.xml
+++ b/app/src/main/res/values-ur-rPK/strings.xml
@@ -284,6 +284,14 @@
خودکار صفائی
خودکار صفائی کو فعال کریں
+ ہوم اسکرین وجٹ
+ وجٹ کارروائیاں فعال کریں
+ اسٹوریج معلومات
+ استعمال شدہ
+ خالی
+ کل
+ صفائی کریں
+ Can\'t display widget content
پیکیجز حذف کرنے کی درخواست کریں [REQUEST_DELETE_PACKAGES]
ایپ کو پیکیجز کو حذف کرنے کی درخواست کرنے کی اجازت دیتا ہے۔ اسے آلے سے دیگر ایپس کو ان انسٹال کرنے کے لیے استعمال کیا جا سکتا ہے۔
diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml
index 6dbd2a1d..52de854c 100644
--- a/app/src/main/res/values-vi-rVN/strings.xml
+++ b/app/src/main/res/values-vi-rVN/strings.xml
@@ -278,6 +278,14 @@
Tự động dọn dẹp
Bật làm sạch tự động
+ Tiện ích Màn hình chính
+ Bật hành động của tiện ích
+ Thông tin lưu trữ
+ Đã dùng
+ Còn trống
+ Tổng cộng
+ Dọn dẹp
+ Can\'t display widget content
Yêu cầu xóa gói [REQUEST_DELETE_PACKAGES]
Cho phép ứng dụng yêu cầu xóa các gói. Điều này có thể được sử dụng để gỡ cài đặt các ứng dụng khác khỏi thiết bị
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 8114de04..6ded6689 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -278,6 +278,14 @@
自動清理
啟用自動清潔
+ 主畫面小工具
+ 啟用小工具操作
+ 儲存空間資訊
+ 已用
+ 可用
+ 總計
+ 清理
+ Can\'t display widget content
請求刪除套件 [REQUEST_DELETE_PACKAGES]
允許應用程式請求刪除套件。這可用於從裝置解除安裝其他應用程式
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 50b54f4c..67d04f78 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -284,6 +284,14 @@
Automatic Cleanup
Enable automatic cleaning
+ Home Screen Widget
+ Enable widget actions
+ Storage Insights
+ Used
+ Free
+ Total
+ Clean Up
+ Can\'t display widget content
Request delete packages [REQUEST_DELETE_PACKAGES]
Allows the app to request the deletion of packages. This can be used to uninstall other apps from the device
diff --git a/app/src/main/res/xml/cleaner_widget_info.xml b/app/src/main/res/xml/cleaner_widget_info.xml
new file mode 100644
index 00000000..ebbce047
--- /dev/null
+++ b/app/src/main/res/xml/cleaner_widget_info.xml
@@ -0,0 +1,8 @@
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e0533944..f3227807 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -14,6 +14,9 @@ androidx-constraintlayout-compose = { module = "androidx.constraintlayout:constr
coil3-coil-video = { module = "io.coil-kt.coil3:coil-video", version.ref = "coilVideoVersion" }
compressor = { module = "id.zelory:compressor", version.ref = "compressor" }
lottie-compose = { module = "com.airbnb.android:lottie-compose", version.ref = "lottie" }
+glance = { module = "androidx.glance:glance", version = "1.1.1" }
+glance-appwidget = { module = "androidx.glance:glance-appwidget", version = "1.1.1" }
+glance-material3 = { module = "androidx.glance:glance-material3", version = "1.1.1" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }