mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
only ask for notifications after login
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "5651f3201d3521ce45fda80b053e6722",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "application",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `name` TEXT NOT NULL, `relays` TEXT NOT NULL, `url` TEXT NOT NULL, `icon` TEXT NOT NULL, `description` TEXT NOT NULL, `pubKey` TEXT NOT NULL, `isConnected` INTEGER NOT NULL, `secret` TEXT NOT NULL, PRIMARY KEY(`key`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "key",
|
||||
"columnName": "key",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "relays",
|
||||
"columnName": "relays",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "url",
|
||||
"columnName": "url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon",
|
||||
"columnName": "icon",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "description",
|
||||
"columnName": "description",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pubKey",
|
||||
"columnName": "pubKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isConnected",
|
||||
"columnName": "isConnected",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "secret",
|
||||
"columnName": "secret",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"key"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_key",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"key"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_key` ON `${TABLE_NAME}` (`key`)"
|
||||
},
|
||||
{
|
||||
"name": "index_name",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"name"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_name` ON `${TABLE_NAME}` (`name`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "applicationPermission",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `pkKey` TEXT NOT NULL, `type` TEXT NOT NULL, `kind` INTEGER, `acceptable` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`pkKey`) REFERENCES `application`(`key`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "pkKey",
|
||||
"columnName": "pkKey",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "kind",
|
||||
"columnName": "kind",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "acceptable",
|
||||
"columnName": "acceptable",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "permissions_by_pk_key",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"pkKey"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `permissions_by_pk_key` ON `${TABLE_NAME}` (`pkKey`)"
|
||||
},
|
||||
{
|
||||
"name": "permissions_unique",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"pkKey",
|
||||
"type",
|
||||
"kind"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `permissions_unique` ON `${TABLE_NAME}` (`pkKey`, `type`, `kind`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "application",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"pkKey"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5651f3201d3521ce45fda80b053e6722')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,20 @@
|
||||
package com.greenart7c3.nostrsigner
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.greenart7c3.nostrsigner.database.AppDatabase
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.service.PushNotificationUtils
|
||||
import com.greenart7c3.nostrsigner.ui.AccountScreen
|
||||
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
|
||||
import com.greenart7c3.nostrsigner.ui.theme.NostrSignerTheme
|
||||
@@ -38,46 +26,6 @@ import kotlinx.coroutines.withContext
|
||||
fun Intent.isLaunchFromHistory(): Boolean = this.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private val requestPermissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { isGranted: Boolean ->
|
||||
if (isGranted) {
|
||||
initNotifications()
|
||||
} else {
|
||||
if (LocalPreferences.shouldShowRationale() == null) {
|
||||
LocalPreferences.updateShoulShowRationale(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initNotifications() {
|
||||
runBlocking {
|
||||
PushNotificationUtils.init(LocalPreferences.allSavedAccounts())
|
||||
}
|
||||
}
|
||||
|
||||
private fun askNotificationPermission(onShouldShowRequestPermissionRationale: () -> Unit) {
|
||||
// This is only necessary for API level >= 33 (TIRAMISU)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (ContextCompat.checkSelfPermission(this, "android.permission.POST_NOTIFICATIONS") != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
val shouldShowRationale = LocalPreferences.shouldShowRationale()
|
||||
if (shouldShowRationale == null) {
|
||||
requestPermissionLauncher.launch("android.permission.POST_NOTIFICATIONS")
|
||||
return
|
||||
}
|
||||
|
||||
if (!shouldShowRationale) {
|
||||
return
|
||||
}
|
||||
|
||||
onShouldShowRequestPermissionRationale()
|
||||
}
|
||||
} else {
|
||||
requestPermissionLauncher.launch("android.permission.POST_NOTIFICATIONS")
|
||||
}
|
||||
}
|
||||
|
||||
private val intents = MutableStateFlow<List<IntentData>>(listOf())
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -85,14 +33,7 @@ class MainActivity : AppCompatActivity() {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
installSplashScreen()
|
||||
|
||||
initNotifications()
|
||||
|
||||
setContent {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
askNotificationPermission {
|
||||
showDialog = true
|
||||
}
|
||||
|
||||
if (intent.isLaunchFromHistory()) {
|
||||
Log.d("isLaunchFromHistory", "Cleared intent history")
|
||||
intent = Intent()
|
||||
@@ -113,40 +54,6 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
NostrSignerTheme {
|
||||
if (showDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
showDialog = false
|
||||
},
|
||||
title = {
|
||||
Text(text = "Permission Needed")
|
||||
},
|
||||
text = {
|
||||
Text(text = "Notifications are needed to use Amber as a nsec bunker.")
|
||||
},
|
||||
confirmButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
showDialog = false
|
||||
requestPermissionLauncher.launch("android.permission.POST_NOTIFICATIONS")
|
||||
}
|
||||
) {
|
||||
Text(text = "Allow")
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
showDialog = false
|
||||
LocalPreferences.updateShoulShowRationale(false)
|
||||
}
|
||||
) {
|
||||
Text(text = "Deny")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
|
||||
@@ -3,8 +3,13 @@ package com.greenart7c3.nostrsigner.ui
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
@@ -25,6 +30,8 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ExpandMore
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
@@ -44,6 +51,7 @@ import androidx.compose.material3.TooltipDefaults
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.material3.rememberTooltipState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -64,6 +72,7 @@ import androidx.compose.ui.text.toUpperCase
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
@@ -443,6 +452,39 @@ fun EditAppDialog(permission: ApplicationEntity, onClose: () -> Unit, onPost: (S
|
||||
}
|
||||
}
|
||||
|
||||
private fun askNotificationPermission(
|
||||
context: Context,
|
||||
requestPermissionLauncher: ManagedActivityResultLauncher<String, Boolean>,
|
||||
onShouldShowRequestPermissionRationale: () -> Unit
|
||||
) {
|
||||
if (ContextCompat.checkSelfPermission(context, "android.permission.POST_NOTIFICATIONS") == PackageManager.PERMISSION_GRANTED) {
|
||||
initNotifications()
|
||||
return
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
val shouldShowRationale = LocalPreferences.shouldShowRationale()
|
||||
if (shouldShowRationale == null) {
|
||||
requestPermissionLauncher.launch("android.permission.POST_NOTIFICATIONS")
|
||||
return
|
||||
}
|
||||
|
||||
if (!shouldShowRationale) {
|
||||
return
|
||||
}
|
||||
|
||||
onShouldShowRequestPermissionRationale()
|
||||
} else {
|
||||
requestPermissionLauncher.launch("android.permission.POST_NOTIFICATIONS")
|
||||
}
|
||||
}
|
||||
|
||||
private fun initNotifications() {
|
||||
runBlocking {
|
||||
PushNotificationUtils.init(LocalPreferences.allSavedAccounts())
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainScreen(
|
||||
@@ -466,6 +508,63 @@ fun MainScreen(
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
|
||||
val requestPermissionLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestPermission()
|
||||
) { isGranted: Boolean ->
|
||||
if (isGranted) {
|
||||
initNotifications()
|
||||
} else {
|
||||
if (LocalPreferences.shouldShowRationale() == null) {
|
||||
LocalPreferences.updateShoulShowRationale(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
val context = LocalContext.current
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
askNotificationPermission(
|
||||
context,
|
||||
requestPermissionLauncher
|
||||
) {
|
||||
showDialog = true
|
||||
}
|
||||
}
|
||||
|
||||
if (showDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
showDialog = false
|
||||
},
|
||||
title = {
|
||||
Text(text = "Permission Needed")
|
||||
},
|
||||
text = {
|
||||
Text(text = "Notifications are needed to use Amber as a nsec bunker.")
|
||||
},
|
||||
confirmButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
showDialog = false
|
||||
requestPermissionLauncher.launch("android.permission.POST_NOTIFICATIONS")
|
||||
}
|
||||
) {
|
||||
Text(text = "Allow")
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
showDialog = false
|
||||
LocalPreferences.updateShoulShowRationale(false)
|
||||
}
|
||||
) {
|
||||
Text(text = "Deny")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
floatingActionButton = {
|
||||
if (navBackStackEntry?.destination?.route == "Permissions") {
|
||||
|
||||
Reference in New Issue
Block a user