Compare commits

..
11 Commits
Author SHA1 Message Date
omni 24a1e704ca update: updated versions 2026-06-17 20:24:19 +03:00
omni a7b3097a03 refactor: use navigation drawer instead bottom bar 2026-06-17 20:23:49 +03:00
omni ff64f431f6 update: updated versions 2026-06-17 09:48:53 +03:00
omni 50b2a965b4 fix: fixed paddings 2026-06-17 09:25:49 +03:00
omni 123af530ed update: updated versions 2026-06-15 22:20:46 +03:00
omni 564245aa08 update: changed code size 2026-06-15 22:19:58 +03:00
omni 2277ae340c fix: fixed translations 2026-06-15 21:26:06 +03:00
omni edcaf6e02c fix: fixed closing action bar 2026-06-15 18:50:47 +03:00
omni da33a6813b feat: added animations 2026-06-15 18:43:03 +03:00
omni ca355f4135 update: updated versions 2026-06-15 17:34:59 +03:00
omni 4a5355e633 Merge pull request 'Added translations' (#1) from translations into main
Reviewed-on: #1
2026-06-15 14:33:00 +00:00
13 changed files with 160 additions and 101 deletions
+4 -1
View File
@@ -23,12 +23,15 @@ android {
minSdk = 30
targetSdk = 36
versionCode = generateVersionCode()
versionName = "2.3.1"
versionName = "2.6.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
applicationIdSuffix = ".debug"
}
release {
isMinifyEnabled = false
proguardFiles(
Binary file not shown.
Binary file not shown.
@@ -131,7 +131,7 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
)
}
Page("Backup", innerPadding) {
Page(stringResource(R.string.backup), innerPadding) {
FullWidthButton(
onClick = {
createBackupLauncher.launch("omnicards-backup.json")
@@ -1,7 +1,10 @@
package ru.omni_devel.cards
import android.content.Intent
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -17,17 +20,25 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
@@ -36,36 +47,103 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.graphics.toColorInt
import kotlinx.coroutines.launch
@Composable
fun Page(name: String, innerPadding: PaddingValues, content: @Composable () -> Unit) {
Column() {
TopBar(name, innerPadding)
fun Page(name: String, innerPadding: PaddingValues, pages: List<NavigationPageData>? = null, content: @Composable () -> Unit) {
val activityContext = LocalActivity.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
.background(MaterialTheme.colorScheme.background)
) {
content()
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
BackHandler(
enabled = pages != null && drawerState.isOpen
) {
scope.launch {
drawerState.close()
}
}
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
if (pages != null) {
ModalDrawerSheet(
modifier = Modifier.background(MaterialTheme.colorScheme.background).padding(8.dp)
) {
for (page in pages) {
NavigationDrawerItem(
label = { Text(page.name) },
selected = false,
onClick = {
scope.launch { drawerState.close() }
if (page.pageClass != null) {
val intent = Intent(activityContext, page.pageClass)
activityContext!!.startActivity(intent)
} else if (page.onClick != null) {
page.onClick()
}
}
)
}
}
}
}
) {
Scaffold(
topBar = {
TopBar(name, innerPadding, if (pages != null) {
{
Text(
"",
fontSize = 24.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier.clickable() {
scope.launch {
drawerState.open()
}
}
)
}
} else null)
}
) { padding ->
Box(
modifier = Modifier
.padding(padding)
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = 16.dp)
.padding(top = 16.dp)
) {
Column() {
content()
}
}
}
}
}
@Composable
fun TopBar(text: String, innerPadding: PaddingValues) {
fun TopBar(text: String, innerPadding: PaddingValues, openMenuButton: (@Composable () -> Unit)? = null) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.primaryContainer)
.padding(top = innerPadding.calculateTopPadding())
.padding(horizontal = 8.dp)
.padding(bottom = 8.dp)
.padding(vertical = 12.dp, horizontal = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
if (openMenuButton != null) {
openMenuButton()
}
Text(
text,
modifier = Modifier.padding(vertical = 4.dp, horizontal = 12.dp),
modifier = Modifier,
fontSize = 24.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer
)
@@ -4,9 +4,19 @@ import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -28,15 +38,20 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import ru.omni_devel.cards.ui.theme.OmniCardsTheme
private const val ANIMATION_DELAY = 300L
class MainActivity : ComponentActivity() {
private lateinit var db: DbHelper
@@ -82,17 +97,33 @@ fun MainPage(
val context = LocalContext.current
val uriHandler = LocalUriHandler.current
var isActionBarShowed by remember { mutableStateOf(false) }
Box(
modifier = Modifier.fillMaxSize()
) {
Page(
stringResource(R.string.app_name),
innerPadding
innerPadding,
pages = listOf(
NavigationPageData(stringResource(R.string.do_add_card), EditCardActivity::class.java),
NavigationPageData(stringResource(R.string.do_sync)) {
Toast.makeText(context, context.getString(R.string.sync_in_progress), Toast.LENGTH_SHORT).show()
sendToWatch(context, "/updateCards", Json.encodeToString(getDbFun().getCards())) { isSuccess ->
if (isSuccess) {
Toast.makeText(context, context.getString(R.string.sync_is_successful), Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, context.getString(R.string.sync_is_fail), Toast.LENGTH_LONG).show()
}
}
},
NavigationPageData(stringResource(R.string.open_backup_menu), BackupActivity::class.java),
NavigationPageData(stringResource(R.string.source_code)) {
uriHandler.openUri("https://github.com/omni-devel/OmniCards")
},
)
) {
Column(
modifier = Modifier.verticalScroll(rememberScrollState()).padding(bottom = 64.dp).background(Color.Transparent).padding(top = 16.dp),
modifier = Modifier.verticalScroll(rememberScrollState()).padding(bottom = 64.dp).background(Color.Transparent),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
if (cards.isEmpty()) {
@@ -108,85 +139,16 @@ fun MainPage(
}
if (isActionBarShowed) {
Column(
Box(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(innerPadding)
.padding(16.dp)
.background(
MaterialTheme.colorScheme.inversePrimary,
RoundedCornerShape(24.dp)
)
.padding(16.dp)
.fillMaxWidth()
) {
FullWidthButton(
onClick = {
isActionBarShowed = false
val intent = Intent(context, EditCardActivity::class.java)
context.startActivity(intent)
}
) {
Text(stringResource(R.string.do_add_card))
}
FullWidthButton(
onClick = {
Toast.makeText(context, context.getString(R.string.sync_in_progress), Toast.LENGTH_SHORT).show()
sendToWatch(context, "/updateCards", Json.encodeToString(getDbFun().getCards())) { isSuccess ->
if (isSuccess) {
Toast.makeText(context, context.getString(R.string.sync_is_successful), Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, context.getString(R.string.sync_is_fail), Toast.LENGTH_LONG).show()
}
}
.fillMaxSize()
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) {
isActionBarShowed = false
}
) {
Text(stringResource(R.string.do_sync))
}
FullWidthButton(
onClick = {
val intent = Intent(context, BackupActivity::class.java)
context.startActivity(intent)
isActionBarShowed = false
}
) {
Text(stringResource(R.string.open_backup_menu))
}
FullWidthButton(
onClick = {
uriHandler.openUri("https://github.com/omni-devel/OmniCards")
isActionBarShowed = false
}
) {
Text(stringResource(R.string.source_code))
}
FullWidthButton(
onClick = {
isActionBarShowed = false
}
) {
Text(">")
}
}
} else {
Button(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(innerPadding).padding(32.dp),
onClick = {
isActionBarShowed = true
}
) {
Text("<")
}
) { }
}
}
}
@@ -0,0 +1,9 @@
package ru.omni_devel.cards
import android.app.Activity
data class NavigationPageData(
val name: String,
val pageClass: Class<out Activity>? = null,
val onClick: (() -> Unit)? = null
)
@@ -2,7 +2,6 @@ package ru.omni_devel.cards
import android.content.Context
import android.graphics.Bitmap
import androidx.compose.ui.platform.LocalContext
import com.google.android.gms.wearable.Wearable
import com.google.zxing.BarcodeFormat
import com.google.zxing.MultiFormatWriter
@@ -10,7 +9,13 @@ import com.journeyapps.barcodescanner.BarcodeEncoder
fun generateCode(value: String, format: BarcodeFormat): Bitmap {
val writer = MultiFormatWriter()
val matrix = writer.encode(value, format, 800, 400)
val (width, height) = when (format) {
BarcodeFormat.QR_CODE, BarcodeFormat.DATA_MATRIX, BarcodeFormat.AZTEC -> 800 to 800
else -> 800 to 400
}
val matrix = writer.encode(value, format, width, height)
return BarcodeEncoder().createBitmap(matrix)
}
+2 -1
View File
@@ -11,7 +11,8 @@
<string name="sync_is_successful">Успешная синхронизация</string>
<string name="sync_is_fail">Ошибка синхронизации. Проверьте подключение к часам</string>
<string name="open_backup_menu">Бэкап/восстановление</string>
<string name="backup">Резервное копирование</string>
<string name="open_backup_menu">Резервное копирование</string>
<string name="do_backup">Сохранить данные</string>
<string name="do_restore">Восстановить данные</string>
<string name="ask_do_restore">Восстановить данные?</string>
+2 -1
View File
@@ -16,7 +16,8 @@
<string name="sync_is_successful">Sync successful</string>
<string name="sync_is_fail">Sync failed. Check your watch connection</string>
<string name="open_backup_menu">Backup / Restore</string>
<string name="backup">Backup</string>
<string name="open_backup_menu">Backup</string>
<string name="do_backup">Save data</string>
<string name="do_restore">Restore data</string>
<string name="ask_do_restore">Restore data?</string>
+1 -1
View File
@@ -23,7 +23,7 @@ android {
minSdk = 30
targetSdk = 36
versionCode = generateVersionCode()
versionName = "1.3.0"
versionName = "1.4.0"
}
buildTypes {
Binary file not shown.
Binary file not shown.