Что вошло:\n- Добавлен полноценный Messages-tab в SearchScreen: поиск по тексту сообщений по всей базе, батчевый проход, параллельная дешифровка, кеш расшифровки, подсветка совпадений, сниппеты и быстрый переход в нужный диалог.\n- В Chats-tab добавлены алиасы для Saved Messages (saved/saved messages/избранное/сохраненные и др.), чтобы чат открывался по текстовому поиску даже без точного username/public key.\n- Для search-бэкенда расширен DAO: getAllMessagesPaged() для постраничного обхода сообщений аккаунта.\n- Исправлена логика клика по @тэгам в сообщениях:\n - переход теперь ведет сразу в чат пользователя (а не в профиль);\n - добавлен fallback-резолв username -> user через локальный диалог, кеш протокола и PacketSearch;\n - добавлен DAO getDialogByUsername() (регистронезависимо и с игнором @).\n- Усилена обработка PacketSearch в ProtocolManager:\n - добавлена очередь ожидания pendingSearchQueries;\n - нормализация query (без @, lowercase);\n - устойчивый матч ответов сервера (raw/normalized/by username);\n - добавлены методы getCachedUserByUsername() и searchUsers().\n- Исправлен конфликт тачей между ClickableSpan и bubble-menu:\n - в AppleEmojiText/AppleEmojiTextView добавлен callback начала тапа по span;\n - улучшен hit-test по span (включая пограничные offset/layout fallback);\n - suppress performClick на span-тапах;\n - в MessageBubble добавлен тайм-guard, чтобы tap по span не открывал context menu.\n- Стабилизирован verified-бейдж в заголовке чата: агрегируется из переданного user, кеша протокола, локальной БД и серверного resolve; отображается консистентно в личных чатах.\n- Улучшен пустой экран Saved Messages при обоях: добавлена аккуратная подложка/бордер и выровненный текст, чтобы контент оставался читабельным на любом фоне.\n- Реализована автосвязка обоев между светлой/темной темами:\n - добавлены pairGroup и mapToTheme/resolveWallpaperForTheme в ThemeWallpapers;\n - добавлены отдельные prefs-ключи для light/dark wallpaper;\n - MainActivity теперь автоматически подбирает и сохраняет обои под активную тему и сохраняет выбор по теме.\n- Биометрия: если на устройстве нет hardware fingerprint, экран включения биометрии не показывается (и доступность возвращает NotAvailable).\n- Небольшие UI-фиксы: поправлено позиционирование галочки в сайдбаре.\n- Техдолг: удалена неиспользуемая зависимость jsoup из build.gradle.
189 lines
6.8 KiB
Kotlin
189 lines
6.8 KiB
Kotlin
plugins {
|
|
id("com.android.application")
|
|
id("org.jetbrains.kotlin.android")
|
|
id("kotlin-kapt")
|
|
id("com.google.gms.google-services")
|
|
}
|
|
|
|
fun safeGitOutput(vararg args: String): String? {
|
|
return runCatching {
|
|
providers
|
|
.exec { commandLine("git", *args) }
|
|
.standardOutput
|
|
.asText
|
|
.get()
|
|
.trim()
|
|
.ifBlank { null }
|
|
}
|
|
.getOrNull()
|
|
}
|
|
|
|
val gitShortSha = safeGitOutput("rev-parse", "--short", "HEAD") ?: "unknown"
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
// Rosetta versioning — bump here on each release
|
|
// ═══════════════════════════════════════════════════════════
|
|
val rosettaVersionName = "1.2.6"
|
|
val rosettaVersionCode = 28 // Increment on each release
|
|
|
|
android {
|
|
namespace = "com.rosetta.messenger"
|
|
compileSdk = 34
|
|
|
|
defaultConfig {
|
|
applicationId = "com.rosetta.messenger"
|
|
minSdk = 24
|
|
targetSdk = 34
|
|
versionCode = rosettaVersionCode
|
|
versionName = rosettaVersionName
|
|
buildConfigField("String", "GIT_SHA", "\"$gitShortSha\"")
|
|
|
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
vectorDrawables { useSupportLibrary = true }
|
|
|
|
// Optimize Lottie animations
|
|
manifestPlaceholders["enableLottieOptimizations"] = "true"
|
|
}
|
|
|
|
signingConfigs {
|
|
create("release") {
|
|
// Using debug keystore for testing - replace with your production keystore
|
|
storeFile = file("${System.getProperty("user.home")}/.android/debug.keystore")
|
|
storePassword = "android"
|
|
keyAlias = "androiddebugkey"
|
|
keyPassword = "android"
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
release {
|
|
isMinifyEnabled = false
|
|
isShrinkResources = false
|
|
proguardFiles(
|
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
"proguard-rules.pro"
|
|
)
|
|
signingConfig = signingConfigs.getByName("release")
|
|
}
|
|
debug {
|
|
// Enable baseline profiles in debug builds too for testing
|
|
// Remove this in production
|
|
}
|
|
}
|
|
compileOptions {
|
|
sourceCompatibility = JavaVersion.VERSION_11
|
|
targetCompatibility = JavaVersion.VERSION_11
|
|
}
|
|
kotlinOptions { jvmTarget = "11" }
|
|
buildFeatures {
|
|
compose = true
|
|
buildConfig = true
|
|
}
|
|
composeOptions { kotlinCompilerExtensionVersion = "1.5.4" }
|
|
packaging {
|
|
resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" }
|
|
jniLibs { useLegacyPackaging = true }
|
|
}
|
|
|
|
applicationVariants.all {
|
|
outputs.all {
|
|
val apkOut = this as com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
|
apkOut.outputFileName = "Rosetta-${versionName}.apk"
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation("androidx.core:core-ktx:1.12.0")
|
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
|
implementation("androidx.activity:activity-compose:1.8.2")
|
|
implementation(platform("androidx.compose:compose-bom:2023.10.01"))
|
|
implementation("androidx.compose.ui:ui")
|
|
implementation("androidx.compose.ui:ui-graphics")
|
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
|
implementation("androidx.compose.material3:material3")
|
|
|
|
// Accompanist for pager and animations
|
|
implementation("com.google.accompanist:accompanist-pager:0.32.0")
|
|
implementation("com.google.accompanist:accompanist-pager-indicators:0.32.0")
|
|
|
|
// Navigation
|
|
implementation("androidx.navigation:navigation-compose:2.7.6")
|
|
|
|
// DataStore for preferences
|
|
implementation("androidx.datastore:datastore-preferences:1.0.0")
|
|
|
|
// Foundation for pager (Compose)
|
|
implementation("androidx.compose.foundation:foundation:1.5.4")
|
|
|
|
// Icons extended
|
|
implementation("androidx.compose.material:material-icons-extended:1.5.4")
|
|
|
|
// Tabler Icons for Compose
|
|
implementation("br.com.devsrsouza.compose.icons:tabler-icons:1.1.0")
|
|
|
|
// Lottie for animations
|
|
implementation("com.airbnb.android:lottie-compose:6.1.0")
|
|
|
|
// Coil for image loading
|
|
implementation("io.coil-kt:coil-compose:2.5.0")
|
|
implementation("io.coil-kt:coil-gif:2.5.0") // For animated WebP/GIF support
|
|
|
|
// uCrop for image cropping
|
|
implementation("com.github.yalantis:ucrop:2.2.8")
|
|
|
|
// PhotoEditor for drawing, filters, text on images
|
|
implementation("com.burhanrashid52:photoeditor:3.0.2")
|
|
|
|
// Blurhash for image placeholders
|
|
implementation("com.vanniktech:blurhash:0.1.0")
|
|
|
|
// Palette for extracting colors from images
|
|
implementation("androidx.palette:palette-ktx:1.0.0")
|
|
|
|
// Crypto libraries for key generation
|
|
implementation("org.bitcoinj:bitcoinj-core:0.16.2")
|
|
implementation("org.bouncycastle:bcprov-jdk15to18:1.77")
|
|
|
|
// Google Tink for XChaCha20-Poly1305
|
|
implementation("com.google.crypto.tink:tink-android:1.10.0")
|
|
|
|
// Security for encrypted storage
|
|
implementation("androidx.security:security-crypto:1.1.0-alpha06")
|
|
|
|
// Room for database
|
|
implementation("androidx.room:room-runtime:2.6.1")
|
|
implementation("androidx.room:room-ktx:2.6.1")
|
|
kapt("androidx.room:room-compiler:2.6.1")
|
|
|
|
// Biometric authentication
|
|
implementation("androidx.biometric:biometric:1.1.0")
|
|
|
|
// CameraX for camera preview
|
|
implementation("androidx.camera:camera-core:1.3.1")
|
|
implementation("androidx.camera:camera-camera2:1.3.1")
|
|
implementation("androidx.camera:camera-lifecycle:1.3.1")
|
|
implementation("androidx.camera:camera-view:1.3.1")
|
|
|
|
// Baseline Profiles for startup performance
|
|
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
|
|
|
|
// Firebase Cloud Messaging
|
|
implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
|
|
implementation("com.google.firebase:firebase-messaging-ktx")
|
|
implementation("com.google.firebase:firebase-analytics-ktx")
|
|
|
|
// Testing dependencies
|
|
testImplementation("junit:junit:4.13.2")
|
|
testImplementation("io.mockk:mockk:1.13.8")
|
|
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
|
|
testImplementation("androidx.arch.core:core-testing:2.2.0")
|
|
|
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
|
androidTestImplementation(platform("androidx.compose:compose-bom:2023.10.01"))
|
|
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
|
debugImplementation("androidx.compose.ui:ui-tooling")
|
|
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
|
}
|