Skip to content

Commit b895bcb

Browse files
Merge pull request #239 from smswithoutborders/dev
Dev
2 parents bd48ab9 + 9db54ec commit b895bcb

66 files changed

Lines changed: 664 additions & 166 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
-16.8 KB
Loading

app/src/main/java/com/example/sw0b_001/Models/Messages/EncryptedContentDAO.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ interface EncryptedContentDAO {
2828
@Delete
2929
fun delete(message: EncryptedContent)
3030

31+
@Delete
32+
fun deleteMultiple(messages: List<EncryptedContent>)
33+
3134
@Query("SELECT * FROM EncryptedContent WHERE id=:encryptedContentId")
3235
fun get(encryptedContentId: Long): EncryptedContent
3336

app/src/main/java/com/example/sw0b_001/Models/Messages/MessagesViewModel.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,13 @@ class MessagesViewModel : ViewModel() {
7070
}
7171
}
7272
}
73+
74+
fun deleteMultiple(context: Context, messages: List<EncryptedContent>, onCompleteCallback: () -> Unit) {
75+
viewModelScope.launch(Dispatchers.Default) {
76+
Datastore.getDatastore(context).encryptedContentDAO().deleteMultiple(messages)
77+
launch(Dispatchers.Main) {
78+
onCompleteCallback()
79+
}
80+
}
81+
}
7382
}

app/src/main/java/com/example/sw0b_001/Models/Platforms/PlatformsViewModel.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ class PlatformsViewModel : ViewModel() {
3535
var message by mutableStateOf<EncryptedContent?>(null)
3636
var bottomTabsItem by mutableStateOf<BottomTabsItems>(BottomTabsItems.BottomBarRecentTab)
3737

38+
// Selection mode properties
39+
var isSelectionMode by mutableStateOf(false)
40+
var selectedMessagesCount by mutableIntStateOf(0)
41+
var onSelectAll: (() -> Unit)? = null
42+
var onDeleteSelected: (() -> Unit)? = null
43+
var onCancelSelection: (() -> Unit)? = null
44+
3845

3946
fun reset() {
4047
platform = null
@@ -66,4 +73,4 @@ class PlatformsViewModel : ViewModel() {
6673
fun getAccount(context: Context, accountIdentifier: String): StoredPlatformsEntity? {
6774
return Datastore.getDatastore(context).storedPlatformsDao().fetchAccount(accountIdentifier)
6875
}
69-
}
76+
}

app/src/main/java/com/example/sw0b_001/ui/appbars/RecentAppBar.kt

Lines changed: 147 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,23 @@ import androidx.compose.foundation.layout.Row
77
import androidx.compose.foundation.layout.Spacer
88
import androidx.compose.foundation.layout.fillMaxWidth
99
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.layout.size
1011
import androidx.compose.foundation.layout.width
1112
import androidx.compose.foundation.text.KeyboardActions
1213
import androidx.compose.foundation.text.KeyboardOptions
1314
import androidx.compose.material.icons.Icons
15+
import androidx.compose.material.icons.filled.AccountCircle
16+
import androidx.compose.material.icons.filled.Cancel
1417
import androidx.compose.material.icons.filled.Close
18+
import androidx.compose.material.icons.filled.Delete
1519
import androidx.compose.material.icons.filled.MoreVert
1620
import androidx.compose.material.icons.filled.Search
21+
import androidx.compose.material.icons.filled.SelectAll
1722
import androidx.compose.material3.CenterAlignedTopAppBar
1823
import androidx.compose.material3.DropdownMenu
1924
import androidx.compose.material3.DropdownMenuItem
2025
import androidx.compose.material3.ExperimentalMaterial3Api
26+
import androidx.compose.material3.HorizontalDivider
2127
import androidx.compose.material3.Icon
2228
import androidx.compose.material3.IconButton
2329
import androidx.compose.material3.MaterialTheme
@@ -39,6 +45,7 @@ import androidx.compose.ui.platform.LocalContext
3945
import androidx.compose.ui.platform.LocalFocusManager
4046
import androidx.compose.ui.res.stringResource
4147
import androidx.compose.ui.text.TextStyle
48+
import androidx.compose.ui.text.font.FontWeight
4249
import androidx.compose.ui.text.input.ImeAction
4350
import androidx.compose.ui.tooling.preview.Preview
4451
import androidx.compose.ui.unit.dp
@@ -47,6 +54,7 @@ import com.example.sw0b_001.R
4754
import com.example.sw0b_001.SettingsActivity
4855
import com.example.sw0b_001.ui.navigation.AboutScreen
4956
import com.example.sw0b_001.ui.theme.AppTheme
57+
import com.example.sw0b_001.utils.getPhoneNumberFromPrefs
5058

5159
@Composable
5260
@OptIn(ExperimentalMaterial3Api::class)
@@ -56,7 +64,12 @@ fun RecentAppBar(
5664
searchQuery: String,
5765
isSearchActive: Boolean,
5866
onToggleSearch: () -> Unit,
59-
onSearchDone: () -> Unit
67+
onSearchDone: () -> Unit,
68+
isSelectionMode: Boolean = false,
69+
selectedCount: Int = 0,
70+
onSelectAll: (() -> Unit)? = null,
71+
onDeleteSelected: (() -> Unit)? = null,
72+
onCancelSelection: (() -> Unit)? = null,
6073
) {
6174
val context = LocalContext.current
6275
val focusManager = LocalFocusManager.current
@@ -72,58 +85,127 @@ fun RecentAppBar(
7285
}
7386
)
7487
}
88+
89+
val phoneNumber = remember { getPhoneNumberFromPrefs(context) }
90+
7591
Column(modifier = Modifier.fillMaxWidth()) {
76-
CenterAlignedTopAppBar(
77-
title = {
78-
if (!isSearchActive) {
79-
Text(stringResource(R.string.app_name))
80-
}
81-
},
82-
actions = {
83-
if (!isSearchActive) {
84-
IconButton(onClick = onToggleSearch) {
92+
if (isSelectionMode) {
93+
// Selection mode app bar
94+
CenterAlignedTopAppBar(
95+
title = {
96+
Text(stringResource(R.string.selected_messages, selectedCount))
97+
},
98+
navigationIcon = {
99+
IconButton(onClick = { onCancelSelection?.invoke() }) {
85100
Icon(
86-
imageVector = Icons.Filled.Search,
87-
contentDescription = stringResource(R.string.search)
101+
imageVector = Icons.Filled.Cancel,
102+
contentDescription = stringResource(R.string.cancel)
103+
)
104+
}
105+
},
106+
actions = {
107+
IconButton(onClick = { onSelectAll?.invoke() }) {
108+
Icon(
109+
imageVector = Icons.Filled.SelectAll,
110+
contentDescription = stringResource(R.string.select_all)
88111
)
89112
}
90-
}
91113

92-
IconButton(onClick = { showMenu = !showMenu }) {
93-
Icon(
94-
imageVector = Icons.Filled.MoreVert,
95-
contentDescription = stringResource(R.string.menu)
96-
)
97-
}
98-
DropdownMenu(
99-
expanded = showMenu,
100-
onDismissRequest = { showMenu = false }
101-
) {
102-
DropdownMenuItem(
103-
text = { Text(stringResource(R.string.settings)) },
104-
onClick = {
105-
context.startActivity(
106-
Intent(context, SettingsActivity::class.java).apply {
107-
flags =
108-
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
109-
}
114+
IconButton(onClick = { onDeleteSelected?.invoke() }) {
115+
Icon(
116+
imageVector = Icons.Filled.Delete,
117+
contentDescription = stringResource(R.string.delete)
118+
)
119+
}
120+
},
121+
colors = TopAppBarDefaults.topAppBarColors(),
122+
scrollBehavior = scrollBehavior,
123+
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
124+
)
125+
} else {
126+
// Normal mode app bar
127+
CenterAlignedTopAppBar(
128+
title = {
129+
if (!isSearchActive) {
130+
Text(stringResource(R.string.app_name))
131+
}
132+
},
133+
actions = {
134+
if (!isSearchActive) {
135+
IconButton(onClick = onToggleSearch) {
136+
Icon(
137+
imageVector = Icons.Filled.Search,
138+
contentDescription = stringResource(R.string.search)
110139
)
111-
showMenu = false
112140
}
113-
)
114-
DropdownMenuItem(
115-
text = { Text(stringResource(R.string.about)) },
116-
onClick = {
117-
navController.navigate(AboutScreen)
118-
showMenu = false
141+
}
142+
143+
IconButton(onClick = { showMenu = !showMenu }) {
144+
Icon(
145+
imageVector = Icons.Filled.MoreVert,
146+
contentDescription = stringResource(R.string.menu)
147+
)
148+
}
149+
DropdownMenu(
150+
expanded = showMenu,
151+
onDismissRequest = { showMenu = false }
152+
) {
153+
if (!phoneNumber.isNullOrBlank()) {
154+
DropdownMenuItem(
155+
text = {
156+
Row(verticalAlignment = Alignment.CenterVertically) {
157+
Icon(
158+
imageVector = Icons.Default.AccountCircle,
159+
contentDescription = stringResource(R.string.your_account),
160+
modifier = Modifier.size(40.dp),
161+
tint = MaterialTheme.colorScheme.onSurfaceVariant
162+
)
163+
Spacer(modifier = Modifier.width(16.dp))
164+
Column {
165+
Text(
166+
text = stringResource(R.string.your_account),
167+
fontWeight = FontWeight.SemiBold,
168+
style = MaterialTheme.typography.bodyMedium
169+
)
170+
Text(
171+
text = phoneNumber,
172+
style = MaterialTheme.typography.bodySmall,
173+
color = MaterialTheme.colorScheme.onSurfaceVariant
174+
)
175+
}
176+
}
177+
},
178+
onClick = { },
179+
enabled = false
180+
)
181+
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
119182
}
120-
)
121-
}
122-
},
123-
colors = TopAppBarDefaults.topAppBarColors(),
124-
scrollBehavior = scrollBehavior,
125-
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
126-
)
183+
DropdownMenuItem(
184+
text = { Text(stringResource(R.string.settings)) },
185+
onClick = {
186+
context.startActivity(
187+
Intent(context, SettingsActivity::class.java).apply {
188+
flags =
189+
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
190+
}
191+
)
192+
showMenu = false
193+
}
194+
)
195+
DropdownMenuItem(
196+
text = { Text(stringResource(R.string.about)) },
197+
onClick = {
198+
navController.navigate(AboutScreen)
199+
showMenu = false
200+
}
201+
)
202+
}
203+
},
204+
colors = TopAppBarDefaults.topAppBarColors(),
205+
scrollBehavior = scrollBehavior,
206+
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
207+
)
208+
}
127209

128210
if (isSearchActive) {
129211
Row(
@@ -183,3 +265,23 @@ fun RecentsAppBarPreview() {
183265
)
184266
}
185267
}
268+
269+
@Preview(showBackground = true)
270+
@Composable
271+
fun RecentsAppBarSelectionModePreview() {
272+
AppTheme(darkTheme = false) {
273+
RecentAppBar(
274+
navController = NavController(context = LocalContext.current),
275+
onSearchQueryChanged = { },
276+
searchQuery = "",
277+
isSearchActive = false,
278+
onToggleSearch = { },
279+
onSearchDone = {},
280+
isSelectionMode = true,
281+
selectedCount = 3,
282+
onSelectAll = { },
283+
onDeleteSelected = { },
284+
onCancelSelection = { }
285+
)
286+
}
287+
}

app/src/main/java/com/example/sw0b_001/ui/features/FeatureInfo.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@ data class FeatureInfo(
1414
object AppFeatures {
1515
val ALL_FEATURES = listOf(
1616
FeatureInfo(
17-
id = "oauth_token_storage_device_setting_info_alert",
17+
id = "view_current_account",
1818
titleRes = R.string.new_feature_title,
19-
descriptionRes = R.string.oauth_token_storage_device_setting_info,
19+
descriptionRes = R.string.view_account_menu,
2020
iconRes = R.drawable.relaysms_icon_default_shape
2121
),
22+
// FeatureInfo(
23+
// id = "oauth_token_storage_device_setting_info_alert",
24+
// titleRes = R.string.new_feature_title,
25+
// descriptionRes = R.string.oauth_token_storage_device_setting_info,
26+
// iconRes = R.drawable.relaysms_icon_default_shape
27+
// ),
2228

2329
)
2430
}

app/src/main/java/com/example/sw0b_001/ui/theme/Theme.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ val unspecified_scheme = ColorFamily(
322322
fun AppTheme(
323323
darkTheme: Boolean = isSystemInDarkTheme(),
324324
// Dynamic color is available on Android 12+
325-
dynamicColor: Boolean = false,
325+
dynamicColor: Boolean = true,
326326
content: @Composable () -> Unit
327327
) {
328328
val colorScheme = when {

app/src/main/java/com/example/sw0b_001/ui/views/HomepageView.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,12 @@ fun HomepageView(
147147
},
148148
onSearchDone = {
149149
isSearchDone = true
150-
}
150+
},
151+
isSelectionMode = platformsViewModel.isSelectionMode,
152+
selectedCount = platformsViewModel.selectedMessagesCount,
153+
onSelectAll = platformsViewModel.onSelectAll,
154+
onDeleteSelected = platformsViewModel.onDeleteSelected,
155+
onCancelSelection = platformsViewModel.onCancelSelection
151156
)
152157
}
153158
}
@@ -415,5 +420,3 @@ fun HomepageViewLoggedInMessages_Preview() {
415420
)
416421
}
417422
}
418-
419-

app/src/main/java/com/example/sw0b_001/ui/views/InboxView.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ fun InboxView(
8282
onClickCallback = {
8383
platformsViewModel.message = message
8484
navController.navigate(BridgeViewScreen)
85-
}
85+
},
86+
logo = TODO(),
87+
isSelected = TODO(),
88+
isSelectionMode = TODO(),
89+
onLongClickCallback = TODO()
8690
)
8791
}
8892
}

app/src/main/java/com/example/sw0b_001/ui/views/OtpCodeVerificationView.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,16 @@ import androidx.compose.ui.unit.dp
6363
import androidx.compose.ui.unit.sp
6464
import androidx.core.app.ActivityCompat.startActivityForResult
6565
import androidx.core.content.ContextCompat
66+
import androidx.core.content.edit
6667
import androidx.navigation.NavController
6768
import androidx.navigation.compose.rememberNavController
69+
import androidx.preference.PreferenceManager
6870
import com.example.sw0b_001.BuildConfig
6971
import com.example.sw0b_001.Models.Platforms.PlatformsViewModel
7072
import com.example.sw0b_001.Models.Vaults
7173
import com.example.sw0b_001.ui.navigation.HomepageScreen
7274
import com.example.sw0b_001.ui.theme.AppTheme
75+
import com.example.sw0b_001.utils.savePhoneNumberToPrefs
7376
import com.google.android.gms.auth.api.phone.SmsRetriever
7477
import com.google.android.gms.common.api.CommonStatusCodes
7578
import com.google.android.gms.common.api.Status
@@ -466,6 +469,8 @@ private fun submitOTPCode(
466469
}
467470
}
468471

472+
savePhoneNumberToPrefs(context, phoneNumber)
473+
469474
vault.refreshStoredTokens(context) {
470475
platformsViewModel.accountsForMissingDialog = it
471476
}
@@ -481,4 +486,5 @@ private fun submitOTPCode(
481486
onCompleteCallback()
482487
}
483488
}
484-
}
489+
}
490+

0 commit comments

Comments
 (0)