Enhancement - optional transparent homoglyph encoding of a few characters in certain languages for more compact and efficient text messages (#4491)

This commit is contained in:
Pavel Vasiliev 2026-02-07 21:49:35 +03:00 committed by GitHub
parent 6ec2ed76ca
commit 4303bfaac4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 297 additions and 4 deletions

View file

@ -30,6 +30,8 @@ import org.meshtastic.core.prefs.emoji.CustomEmojiPrefs
import org.meshtastic.core.prefs.emoji.CustomEmojiPrefsImpl
import org.meshtastic.core.prefs.filter.FilterPrefs
import org.meshtastic.core.prefs.filter.FilterPrefsImpl
import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs
import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefsImpl
import org.meshtastic.core.prefs.map.MapConsentPrefs
import org.meshtastic.core.prefs.map.MapConsentPrefsImpl
import org.meshtastic.core.prefs.map.MapPrefs
@ -54,6 +56,10 @@ import javax.inject.Singleton
@Retention(AnnotationRetention.BINARY)
internal annotation class AnalyticsSharedPreferences
@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class HomoglyphEncodingSharedPreferences
@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class AppSharedPreferences
@ -101,6 +107,8 @@ interface PrefsModule {
@Binds fun bindAnalyticsPrefs(analyticsPrefsImpl: AnalyticsPrefsImpl): AnalyticsPrefs
@Binds fun bindHomoglyphEncodingPrefs(homoglyphEncodingPrefsImpl: HomoglyphPrefsImpl): HomoglyphPrefs
@Binds fun bindCustomEmojiPrefs(customEmojiPrefsImpl: CustomEmojiPrefsImpl): CustomEmojiPrefs
@Binds fun bindMapConsentPrefs(mapConsentPrefsImpl: MapConsentPrefsImpl): MapConsentPrefs
@ -127,6 +135,12 @@ interface PrefsModule {
fun provideAnalyticsSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
context.getSharedPreferences("analytics-prefs", Context.MODE_PRIVATE)
@Provides
@Singleton
@HomoglyphEncodingSharedPreferences
fun provideHomoglyphEncodingSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
context.getSharedPreferences("homoglyph-encoding-prefs", Context.MODE_PRIVATE)
@Provides
@Singleton
@AppSharedPreferences

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2026 Meshtastic LLC
*
* 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, either version 3 of the License, or
* (at your option) any later version.
*
* 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 org.meshtastic.core.prefs.homoglyph
import android.content.SharedPreferences
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import org.meshtastic.core.prefs.PrefDelegate
import org.meshtastic.core.prefs.di.HomoglyphEncodingSharedPreferences
import javax.inject.Inject
import javax.inject.Singleton
interface HomoglyphPrefs {
/** Preference for whether homoglyph encoding is enabled by the user. */
var homoglyphEncodingEnabled: Boolean
/**
* Provides a [Flow] that emits the current state of [homoglyphEncodingEnabled] and subsequent changes.
*
* @return A [Flow] of [Boolean] indicating if homoglyph encoding is enabled.
*/
fun getHomoglyphEncodingEnabledChangesFlow(): Flow<Boolean>
companion object {
/** Key for the homoglyphEncodingEnabled preference. */
const val KEY_HOMOGLYPH_ENCODING_ENABLED = "enabled"
}
}
@Singleton
class HomoglyphPrefsImpl
@Inject
constructor(
@HomoglyphEncodingSharedPreferences private val homoglyphEncodingSharedPreferences: SharedPreferences,
) : HomoglyphPrefs {
override var homoglyphEncodingEnabled: Boolean by
PrefDelegate(homoglyphEncodingSharedPreferences, HomoglyphPrefs.KEY_HOMOGLYPH_ENCODING_ENABLED, false)
override fun getHomoglyphEncodingEnabledChangesFlow(): Flow<Boolean> = callbackFlow {
val listener =
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
if (key == HomoglyphPrefs.KEY_HOMOGLYPH_ENCODING_ENABLED) {
trySend(homoglyphEncodingEnabled)
}
}
// Emit the initial value
trySend(homoglyphEncodingEnabled)
homoglyphEncodingSharedPreferences.registerOnSharedPreferenceChangeListener(listener)
awaitClose { homoglyphEncodingSharedPreferences.unregisterOnSharedPreferenceChangeListener(listener) }
}
}

View file

@ -294,6 +294,7 @@
<string name="theme_system">System default</string>
<string name="choose_theme">Choose theme</string>
<string name="provide_location_to_mesh">Provide phone location to mesh</string>
<string name="use_homoglyph_characters_encoding">Compact encoding for Cyrillic</string>
<plurals name="delete_messages">
<item quantity="one">Delete message?</item>
<item quantity="other">Delete %1$s messages?</item>