fix: фикс смены иконки в FCM версии, реальный выход с аккаунта(server-side)

This commit is contained in:
Jganenokk
2026-07-06 22:59:53 +07:00
parent 27a1b504e4
commit e1c9d2584f
6 changed files with 58 additions and 21 deletions
+3 -3
View File
@@ -33,7 +33,7 @@
android:enableOnBackInvokedCallback="true"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:name="ru.komet.app.MainActivity"
android:exported="true"
android:icon="@mipmap/ic_launcher"
android:label="Komet"
@@ -73,12 +73,12 @@
</intent-filter>
</activity>
<activity-alias
android:name=".MinimalIcon"
android:name="ru.komet.app.MinimalIcon"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/ic_launcher_minimal"
android:label="Komet"
android:targetActivity=".MainActivity">
android:targetActivity="ru.komet.app.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@@ -52,7 +52,11 @@ import java.util.concurrent.atomic.AtomicBoolean
class MainActivity : FlutterActivity() {
private val channelName = "ru.komet.app/vpn_bypass"
private val iconComponents = listOf("MainActivity", "MinimalIcon")
private val iconPackage = MainActivity::class.java.name.substringBeforeLast('.')
private val iconComponents = mapOf(
"MainActivity" to "$iconPackage.MainActivity",
"MinimalIcon" to "$iconPackage.MinimalIcon",
)
private var nfcAdapter: NfcAdapter? = null
private var nfcEvents: EventChannel.EventSink? = null
@@ -86,8 +90,8 @@ class MainActivity : FlutterActivity() {
private fun applyIcon(name: String) {
val pm = packageManager
for (alias in iconComponents) {
val component = ComponentName(packageName, "$packageName.$alias")
for ((alias, className) in iconComponents) {
val component = ComponentName(packageName, className)
val state = if (alias == name) {
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
} else {
@@ -165,7 +169,7 @@ class MainActivity : FlutterActivity() {
when (call.method) {
"setAppIcon" -> {
val name = call.argument<String>("name")
if (name == null || !iconComponents.contains(name)) {
if (name == null || !iconComponents.containsKey(name)) {
result.error("INVALID_ICON", "Unknown icon: $name", null)
return@setMethodCallHandler
}
+34 -1
View File
@@ -396,10 +396,16 @@ class AccountModule {
}
Future<void> logout() async {
final accountId = await TokenStorage.getActiveAccountId();
try {
await _logoutOnServer(accountId);
} on SessionExpiredException catch (e) {
logger.w('logout: сервер отклонил сессию: ${e.message}');
}
_loggedIn = false;
try {
await _api.disconnect();
} catch (_) {}
final accountId = await TokenStorage.getActiveAccountId();
if (accountId != null) {
await removeAccount(accountId);
}
@@ -409,6 +415,33 @@ class AccountModule {
chats.resetForAccountSwitch();
}
Future<void> _logoutOnServer(int? accountId) async {
await _ensureLogoutSession(accountId);
await _api.sendRequestOrThrow(Opcode.logout, <dynamic, dynamic>{});
}
Future<void> _ensureLogoutSession(int? accountId) async {
if (_api.state == SessionState.disconnected) {
await _api.connect();
}
if (_api.state != SessionState.online) {
await _api.stateStream
.firstWhere((state) => state == SessionState.online)
.timeout(const Duration(seconds: 20));
}
if (_loggedIn) return;
if (accountId == null) return;
final token = await TokenStorage.readToken(accountId);
if (token == null || token.isEmpty) {
throw StateError('logout: нет токена для серверного выхода');
}
await _api.sendRequestOrThrow(
Opcode.login,
buildLoginPayload(token, interactive: false),
);
_loggedIn = true;
}
Future<TwoFactorResult> checkPassword({
required String password,
required String trackId,
@@ -91,15 +91,9 @@ class PrivacyModule extends AccountApiBase {
}
}
Future<void> unregisterPushToken(String pushToken) async {
Future<void> unregisterPushToken(String _) async {
if (api.state != SessionState.online) return;
final accountId = await TokenStorage.getActiveAccountId();
if (accountId == null) return;
final authToken = await TokenStorage.readToken(accountId);
if (authToken == null) return;
await api.sendRequest(Opcode.logout, <dynamic, dynamic>{
'token': authToken,
'pushToken': pushToken,
});
final packet = await api.sendRequest(Opcode.logout, <dynamic, dynamic>{});
throwIfPacketError(packet);
}
}
+3 -3
View File
@@ -36,12 +36,12 @@ class AppIconConfig {
static Future<void> apply(AppIcon icon) async {
if (!isSupported) return;
if (current.value == icon) return;
final prefs = await SharedPreferences.getInstance();
await prefs.setString(prefKey, icon.id);
current.value = icon;
await _channel.invokeMethod<void>('setAppIcon', {
'name': icon.platformName,
});
final prefs = await SharedPreferences.getInstance();
await prefs.setString(prefKey, icon.id);
current.value = icon;
}
static AppIcon _parse(String? val) {
@@ -17,6 +17,7 @@ import '../../widgets/info_action_sheet.dart';
import '../../widgets/komet_avatar.dart';
import '../../widgets/settings_card.dart';
import '../../widgets/sheet_helpers.dart';
import '../../widgets/custom_notification.dart';
import '../auth/login_screen.dart';
import '../auth/proxy_settings_sheet.dart';
import '../../../core/config/app_digital_id_mode.dart';
@@ -198,7 +199,12 @@ class _SettingsTabState extends State<SettingsTab> {
Future<void> _doLogout() async {
final navState = KometApp.navigatorKey.currentState;
await accountModule.logout();
try {
await accountModule.logout();
} catch (e) {
if (mounted) showCustomNotification(context, 'Не удалось выйти: $e');
return;
}
await resetDigitalIdSession();
try {
await api.connect();