Port Komet UI improvements and implement IKAR ghost mode
Tests / test (push) Canceled after 0s
Build Android (FCM) / build-android-fcm (push) Canceled after 0s
Build Android / build-android (push) Canceled after 0s
Build iOS / build-ios (push) Canceled after 0s
Build Linux / build-linux (push) Canceled after 0s
Build macOS / build-macos (push) Canceled after 0s
Build Windows / build-windows (push) Canceled after 0s
Native crypto / native-crypto (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s

Adapt video editing, decrypted message actions, custom themes and gestures from PR 166. Track visible server presence per session and preserve delivery for invisible clients.
This commit is contained in:
sevenhill
2026-10-07 22:07:05 +03:00
parent 69ea5091eb
commit 1ef2b7420e
35 changed files with 2210 additions and 524 deletions
+117
View File
@@ -0,0 +1,117 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:ikar/core/config/app_wallpaper_tint.dart';
import 'package:ikar/core/storage/app_database.dart';
import 'package:ikar/core/storage/chat_wallpaper_store.dart';
import 'package:ikar/core/utils/haptics.dart';
import 'package:ikar/frontend/screens/profile/custom_gradient_editor_screen.dart';
import 'package:ikar/frontend/screens/profile/theme_settings_screen.dart';
import 'package:ikar/l10n/app_localizations.dart';
import 'package:ikar/main.dart' show api;
import 'package:shared_preferences/shared_preferences.dart';
class _Paths extends PathProviderPlatform {
_Paths(this.path);
final String path;
@override
Future<String?> getApplicationSupportPath() async => path;
@override
Future<String?> getApplicationDocumentsPath() async => path;
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
testWidgets(
'custom theme edits the global gradient and keeps chat overrides',
(tester) async {
final previousPaths = PathProviderPlatform.instance;
late Directory dir;
await tester.runAsync(() async {
api.state;
dir = await Directory.systemTemp.createTemp('ikar-theme-test-');
PathProviderPlatform.instance = _Paths(dir.path);
SharedPreferences.setMockInitialValues({});
Haptics.enabled = false;
await AppWallpaperTint.load();
await AppDatabase.init();
await AppDatabase.saveProfile(ProfileData.stub(42));
await AppDatabase.setActiveAccount(42);
await ChatWallpaperStore.instance.load();
await ChatWallpaperStore.instance.setTheme(
42,
7,
'synthetic-chat-theme',
);
});
addTearDown(() async {
await api.dispose();
await AppDatabase.close();
PathProviderPlatform.instance = previousPaths;
Haptics.enabled = true;
await dir.delete(recursive: true);
});
await tester.pumpWidget(
MaterialApp(
locale: const Locale('ru'),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: const ThemeSettingsScreen(),
),
);
await tester.runAsync(
() => Future<void>.delayed(const Duration(milliseconds: 100)),
);
await tester.pumpAndSettle();
await tester.tap(find.text('Собственная тема'));
await tester.pumpAndSettle();
expect(AppWallpaperTint.current.value, isTrue);
expect(find.text('Настроить'), findsOneWidget);
await tester.tap(find.text('Настроить'));
await tester.pumpAndSettle();
expect(find.byType(CustomGradientEditorScreen), findsOneWidget);
final editorContext = tester.element(
find.byType(CustomGradientEditorScreen),
);
Navigator.of(editorContext).pop(
const CustomGradientResult(
colors: [Colors.red, Colors.blue],
animated: false,
rotation: 0.7,
),
);
await tester.runAsync(
() => Future<void>.delayed(const Duration(milliseconds: 100)),
);
await tester.pumpAndSettle();
final wallpaper = ChatWallpaperStore.instance.get(
42,
kGlobalWallpaperChatId,
)!;
expect(wallpaper.gradientColors!.map((color) => color.toARGB32()), [
Colors.red.toARGB32(),
Colors.blue.toARGB32(),
]);
expect(wallpaper.gradientRotation, 0.7);
expect(
ChatWallpaperStore.instance.get(42, 7)!.themeId,
'synthetic-chat-theme',
);
final restored = ChatWallpaperStore.forTesting();
await tester.runAsync(restored.load);
expect(
restored
.get(42, kGlobalWallpaperChatId)!
.gradientColors!
.map((color) => color.toARGB32()),
[Colors.red.toARGB32(), Colors.blue.toARGB32()],
);
await tester.tap(find.text('Системная'));
await tester.pumpAndSettle();
expect(AppWallpaperTint.current.value, isFalse);
expect(restored.get(42, kGlobalWallpaperChatId), isNotNull);
await tester.pumpWidget(const SizedBox.shrink());
},
);
}