mirror of
https://codeberg.org/timelimit/opentimelimit-android.git
synced 2025-10-05 10:49:29 +02:00
Improve background loop exception presentation
This commit is contained in:
parent
931b884567
commit
bb0decc808
13 changed files with 149 additions and 25 deletions
|
@ -122,6 +122,14 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".ui.diagnose.exception.DiagnoseExceptionActivity"
|
||||||
|
android:theme="@style/AppTheme.Translucent"
|
||||||
|
android:exported="false"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:taskAffinity=":exception"
|
||||||
|
android:launchMode="singleTop" />
|
||||||
|
|
||||||
<!-- system integration -->
|
<!-- system integration -->
|
||||||
|
|
||||||
<receiver android:name=".integration.platform.android.receiver.BootReceiver" android:exported="false">
|
<receiver android:name=".integration.platform.android.receiver.BootReceiver" android:exported="false">
|
||||||
|
|
|
@ -220,7 +220,8 @@ data class AppStatusMessage(
|
||||||
val title: String,
|
val title: String,
|
||||||
val text: String,
|
val text: String,
|
||||||
val subtext: String? = null,
|
val subtext: String? = null,
|
||||||
val showSwitchToDefaultUserOption: Boolean = false
|
val showSwitchToDefaultUserOption: Boolean = false,
|
||||||
|
val showErrorMessage: Boolean = false
|
||||||
): Parcelable
|
): Parcelable
|
||||||
|
|
||||||
data class BatteryStatus(
|
data class BatteryStatus(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,6 +26,7 @@ import io.timelimit.android.logic.DefaultAppLogic
|
||||||
import io.timelimit.android.sync.actions.SignOutAtDeviceAction
|
import io.timelimit.android.sync.actions.SignOutAtDeviceAction
|
||||||
import io.timelimit.android.sync.actions.apply.ApplyActionUtil
|
import io.timelimit.android.sync.actions.apply.ApplyActionUtil
|
||||||
import io.timelimit.android.ui.MainActivity
|
import io.timelimit.android.ui.MainActivity
|
||||||
|
import io.timelimit.android.ui.diagnose.exception.DiagnoseExceptionActivity
|
||||||
|
|
||||||
class BackgroundActionService: Service() {
|
class BackgroundActionService: Service() {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -36,7 +37,7 @@ class BackgroundActionService: Service() {
|
||||||
fun prepareRevokeTemporarilyAllowed(context: Context) = Intent(context, BackgroundActionService::class.java)
|
fun prepareRevokeTemporarilyAllowed(context: Context) = Intent(context, BackgroundActionService::class.java)
|
||||||
.putExtra(ACTION, ACTION_REVOKE_TEMPORARILY_ALLOWED_APPS)
|
.putExtra(ACTION, ACTION_REVOKE_TEMPORARILY_ALLOWED_APPS)
|
||||||
|
|
||||||
fun getSwitchToDefaultUserIntent(context: Context) = PendingIntent.getService(
|
fun getSwitchToDefaultUserIntent(context: Context): PendingIntent = PendingIntent.getService(
|
||||||
context,
|
context,
|
||||||
PendingIntentIds.SWITCH_TO_DEFAULT_USER,
|
PendingIntentIds.SWITCH_TO_DEFAULT_USER,
|
||||||
Intent(context, BackgroundActionService::class.java)
|
Intent(context, BackgroundActionService::class.java)
|
||||||
|
@ -44,12 +45,22 @@ class BackgroundActionService: Service() {
|
||||||
PendingIntentIds.PENDING_INTENT_FLAGS
|
PendingIntentIds.PENDING_INTENT_FLAGS
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getOpenAppIntent(context: Context) = PendingIntent.getActivity(
|
fun getOpenAppIntent(context: Context): PendingIntent = PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
PendingIntentIds.OPEN_MAIN_APP,
|
PendingIntentIds.OPEN_MAIN_APP,
|
||||||
Intent(context, MainActivity::class.java),
|
Intent(context, MainActivity::class.java),
|
||||||
PendingIntentIds.PENDING_INTENT_FLAGS
|
PendingIntentIds.PENDING_INTENT_FLAGS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun getOpenAppWithErrorIntent(context: Context): PendingIntent = PendingIntent.getActivities(
|
||||||
|
context,
|
||||||
|
PendingIntentIds.OPEN_MAIN_APP_WITH_ERROR,
|
||||||
|
arrayOf(
|
||||||
|
Intent(context, MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
|
||||||
|
Intent(context, DiagnoseExceptionActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
),
|
||||||
|
PendingIntentIds.PENDING_INTENT_FLAGS
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val notificationManager: NotificationManager by lazy {
|
private val notificationManager: NotificationManager by lazy {
|
||||||
|
|
|
@ -84,7 +84,12 @@ class BackgroundService: Service() {
|
||||||
.setContentTitle(appStatusMessage.title)
|
.setContentTitle(appStatusMessage.title)
|
||||||
.setContentText(appStatusMessage.text)
|
.setContentText(appStatusMessage.text)
|
||||||
.setSubText(appStatusMessage.subtext)
|
.setSubText(appStatusMessage.subtext)
|
||||||
.setContentIntent(BackgroundActionService.getOpenAppIntent(context))
|
.setContentIntent(
|
||||||
|
if (appStatusMessage.showErrorMessage)
|
||||||
|
BackgroundActionService.getOpenAppWithErrorIntent(context)
|
||||||
|
else
|
||||||
|
BackgroundActionService.getOpenAppIntent(context)
|
||||||
|
)
|
||||||
.setWhen(0)
|
.setWhen(0)
|
||||||
.setShowWhen(false)
|
.setShowWhen(false)
|
||||||
.setSound(null)
|
.setSound(null)
|
||||||
|
|
|
@ -29,6 +29,7 @@ object NotificationIds {
|
||||||
const val REVOKE_TEMPORARILY_ALLOWED_APPS = 3
|
const val REVOKE_TEMPORARILY_ALLOWED_APPS = 3
|
||||||
const val TIME_WARNING = 4
|
const val TIME_WARNING = 4
|
||||||
const val EXTRA_TIME_STARTED = 5
|
const val EXTRA_TIME_STARTED = 5
|
||||||
|
const val OPEN_MAIN_APP_WITH_ERROR = 6
|
||||||
}
|
}
|
||||||
|
|
||||||
object NotificationChannels {
|
object NotificationChannels {
|
||||||
|
@ -133,6 +134,7 @@ object PendingIntentIds {
|
||||||
const val SWITCH_TO_DEFAULT_USER = 3
|
const val SWITCH_TO_DEFAULT_USER = 3
|
||||||
const val U2F_NFC_DISCOVERY = 4
|
const val U2F_NFC_DISCOVERY = 4
|
||||||
const val U2F_USB_RESPONSE = 5
|
const val U2F_USB_RESPONSE = 5
|
||||||
|
const val OPEN_MAIN_APP_WITH_ERROR = 6
|
||||||
|
|
||||||
val PENDING_INTENT_FLAGS = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
val PENDING_INTENT_FLAGS = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
|
|
@ -777,7 +777,8 @@ class BackgroundTaskLogic(val appLogic: AppLogic) {
|
||||||
appLogic.platformIntegration.setAppStatusMessage(AppStatusMessage(
|
appLogic.platformIntegration.setAppStatusMessage(AppStatusMessage(
|
||||||
appLogic.context.getString(R.string.background_logic_error),
|
appLogic.context.getString(R.string.background_logic_error),
|
||||||
appLogic.context.getString(R.string.background_logic_error_internal),
|
appLogic.context.getString(R.string.background_logic_error_internal),
|
||||||
showSwitchToDefaultUserOption = deviceRelatedData.canSwitchToDefaultUser
|
showSwitchToDefaultUserOption = deviceRelatedData.canSwitchToDefaultUser,
|
||||||
|
showErrorMessage = true
|
||||||
))
|
))
|
||||||
appLogic.platformIntegration.setShowBlockingOverlay(false)
|
appLogic.platformIntegration.setShowBlockingOverlay(false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Open TimeLimit Copyright <C> 2019 - 2022 Jonas Lochmann
|
* Open TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,6 +29,7 @@ import io.timelimit.android.extensions.safeNavigate
|
||||||
import io.timelimit.android.livedata.liveDataFromNonNullValue
|
import io.timelimit.android.livedata.liveDataFromNonNullValue
|
||||||
import io.timelimit.android.livedata.liveDataFromNullableValue
|
import io.timelimit.android.livedata.liveDataFromNullableValue
|
||||||
import io.timelimit.android.logic.DefaultAppLogic
|
import io.timelimit.android.logic.DefaultAppLogic
|
||||||
|
import io.timelimit.android.ui.diagnose.exception.DiagnoseExceptionDialogFragment
|
||||||
import io.timelimit.android.ui.main.ActivityViewModelHolder
|
import io.timelimit.android.ui.main.ActivityViewModelHolder
|
||||||
import io.timelimit.android.ui.main.AuthenticationFab
|
import io.timelimit.android.ui.main.AuthenticationFab
|
||||||
import io.timelimit.android.ui.main.FragmentWithCustomTitle
|
import io.timelimit.android.ui.main.FragmentWithCustomTitle
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package io.timelimit.android.ui.diagnose.exception
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import io.timelimit.android.logic.DefaultAppLogic
|
||||||
|
|
||||||
|
class DiagnoseExceptionActivity: FragmentActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
val ex = DefaultAppLogic.with(this).backgroundTaskLogic.lastLoopException.value
|
||||||
|
|
||||||
|
if (ex != null) {
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
DiagnoseExceptionDialogFragment.newInstance(ex, true).show(supportFragmentManager)
|
||||||
|
}
|
||||||
|
} else finish()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* TimeLimit Copyright <C> 2019 Jonas Lochmann
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -13,12 +13,13 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package io.timelimit.android.ui.diagnose
|
package io.timelimit.android.ui.diagnose.exception
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
@ -26,35 +27,26 @@ import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import io.timelimit.android.R
|
import io.timelimit.android.R
|
||||||
import io.timelimit.android.extensions.showSafe
|
import io.timelimit.android.extensions.showSafe
|
||||||
import java.io.PrintWriter
|
|
||||||
import java.io.StringWriter
|
|
||||||
|
|
||||||
class DiagnoseExceptionDialogFragment: DialogFragment() {
|
class DiagnoseExceptionDialogFragment: DialogFragment() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val DIALOG_TAG = "DiagnoseExceptionDialogFragment"
|
private const val DIALOG_TAG = "DiagnoseExceptionDialogFragment"
|
||||||
private const val EXCEPTION = "ex"
|
private const val EXCEPTION = "ex"
|
||||||
|
private const val FINISH_ON_DISMISS = "finish"
|
||||||
|
|
||||||
fun newInstance(exception: Exception) = DiagnoseExceptionDialogFragment().apply {
|
fun newInstance(exception: Exception, finishOnDismiss: Boolean = false) = DiagnoseExceptionDialogFragment().apply {
|
||||||
arguments = Bundle().apply {
|
arguments = Bundle().apply {
|
||||||
putSerializable(EXCEPTION, exception)
|
putSerializable(EXCEPTION, exception)
|
||||||
|
putBoolean(FINISH_ON_DISMISS, finishOnDismiss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStackTraceString(tr: Throwable): String = StringWriter().let { sw ->
|
|
||||||
PrintWriter(sw).let { pw ->
|
|
||||||
tr.printStackTrace(pw)
|
|
||||||
pw.flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
sw.toString()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val message = getStackTraceString(arguments!!.getSerializable(EXCEPTION) as Exception)
|
val message = ExceptionUtil.formatInterpreted(requireContext(), requireArguments().getSerializable(EXCEPTION) as Exception)
|
||||||
val clipboard = context!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
|
||||||
return AlertDialog.Builder(context!!, theme)
|
return AlertDialog.Builder(requireContext(), theme)
|
||||||
.setMessage(message)
|
.setMessage(message)
|
||||||
.setNeutralButton(R.string.diagnose_copy_to_clipboard) { _, _ ->
|
.setNeutralButton(R.string.diagnose_copy_to_clipboard) { _, _ ->
|
||||||
clipboard.setPrimaryClip(ClipData.newPlainText("TimeLimit", message))
|
clipboard.setPrimaryClip(ClipData.newPlainText("TimeLimit", message))
|
||||||
|
@ -65,5 +57,13 @@ class DiagnoseExceptionDialogFragment: DialogFragment() {
|
||||||
.create()
|
.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
|
||||||
|
if (requireArguments().getBoolean(FINISH_ON_DISMISS) && isResumed) {
|
||||||
|
requireActivity().finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun show(fragmentManager: FragmentManager) = showSafe(fragmentManager, DIALOG_TAG)
|
fun show(fragmentManager: FragmentManager) = showSafe(fragmentManager, DIALOG_TAG)
|
||||||
}
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package io.timelimit.android.ui.diagnose.exception
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import io.timelimit.android.R
|
||||||
|
import io.timelimit.android.integration.platform.android.foregroundapp.InstanceIdForegroundAppHelper.InstanceIdException
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.io.StringWriter
|
||||||
|
|
||||||
|
object ExceptionUtil {
|
||||||
|
fun formatInterpreted(context: Context, tr: Throwable): String {
|
||||||
|
val explain = when (tr) {
|
||||||
|
is InstanceIdException.EventsNotSortedByTimestamp -> context.getString(R.string.background_logic_errpr_detailed_instanceid_sorting)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
val tr2 = formatSimple(tr)
|
||||||
|
|
||||||
|
return if (explain != null) "$explain\n\n$tr2"
|
||||||
|
else tr2
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatSimple(tr: Throwable): String = StringWriter().let { sw ->
|
||||||
|
PrintWriter(sw).let { pw ->
|
||||||
|
tr.printStackTrace(pw)
|
||||||
|
pw.flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.toString()
|
||||||
|
}
|
||||||
|
}
|
|
@ -123,6 +123,12 @@
|
||||||
<string name="background_logic_opening_lockscreen">Sperrbildschirm wird geöffnet</string>
|
<string name="background_logic_opening_lockscreen">Sperrbildschirm wird geöffnet</string>
|
||||||
<string name="background_logic_permission_sanction_title">Berechtigung fehlt</string>
|
<string name="background_logic_permission_sanction_title">Berechtigung fehlt</string>
|
||||||
<string name="background_logic_permission_sanction_text">nehme an, dass alles verwendet wird</string>
|
<string name="background_logic_permission_sanction_text">nehme an, dass alles verwendet wird</string>
|
||||||
|
<string name="background_logic_errpr_detailed_instanceid_sorting">Es gibt ein Problem mit der
|
||||||
|
Nutzungsstatisitkdatenbank Ihres Gerätes.
|
||||||
|
Deshalb kann TimeLimit nicht zuverlässig erkennen, welche App verwendet wird.
|
||||||
|
Dieses Problem kann nur behoben werden durch vier Tagen Geduld oder das Zurücksetzen des Gerätes.
|
||||||
|
Eine Neuinstallation von TimeLimit hilft NICHT.
|
||||||
|
</string>
|
||||||
|
|
||||||
<string name="background_logic_temporarily_allowed_title">Apps wurden vorübergehend erlaubt</string>
|
<string name="background_logic_temporarily_allowed_title">Apps wurden vorübergehend erlaubt</string>
|
||||||
<string name="background_logic_temporarily_allowed_text">Zum Rückgängig machen hier tippen oder Bildschirm ausschalten</string>
|
<string name="background_logic_temporarily_allowed_text">Zum Rückgängig machen hier tippen oder Bildschirm ausschalten</string>
|
||||||
|
|
|
@ -154,6 +154,12 @@
|
||||||
<string name="background_logic_opening_lockscreen">Opening lock screen</string>
|
<string name="background_logic_opening_lockscreen">Opening lock screen</string>
|
||||||
<string name="background_logic_permission_sanction_title">Missing permission</string>
|
<string name="background_logic_permission_sanction_title">Missing permission</string>
|
||||||
<string name="background_logic_permission_sanction_text">assuming that everything is used</string>
|
<string name="background_logic_permission_sanction_text">assuming that everything is used</string>
|
||||||
|
<string name="background_logic_errpr_detailed_instanceid_sorting">There is an issue with
|
||||||
|
the data in the usage stats database of your device.
|
||||||
|
Due to that, TimeLimit can not reliable detect the running Apps.
|
||||||
|
You can do nothing to solve this except waiting for four days or doing a reset of the whole device.
|
||||||
|
Reinstalling TimeLimit does NOT help.
|
||||||
|
</string>
|
||||||
|
|
||||||
<string name="background_logic_temporarily_allowed_title">Apps are temporarily allowed</string>
|
<string name="background_logic_temporarily_allowed_title">Apps are temporarily allowed</string>
|
||||||
<string name="background_logic_temporarily_allowed_text">Tap here or turn screen off to undo</string>
|
<string name="background_logic_temporarily_allowed_text">Tap here or turn screen off to undo</string>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
Open TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
|
Open TimeLimit Copyright <C> 2019 - 2024 Jonas Lochmann
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -34,6 +34,10 @@
|
||||||
<item name="colorAccent">@color/white</item>
|
<item name="colorAccent">@color/white</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.Translucent" parent="AppTheme">
|
||||||
|
<item name="android:windowIsFloating">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<!-- from https://stackoverflow.com/a/46286184 -->
|
<!-- from https://stackoverflow.com/a/46286184 -->
|
||||||
<style name="BottomSheetDialog" parent="Theme.MaterialComponents.DayNight.BottomSheetDialog">
|
<style name="BottomSheetDialog" parent="Theme.MaterialComponents.DayNight.BottomSheetDialog">
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue