Skip to content

Commit e777dfc

Browse files
authored
Merge pull request #992 from broxus/release/EWM-TECH_1.15.2
chore(EWM-TECH): release `1.15.2`
2 parents 4d18a5d + 1b9a588 commit e777dfc

File tree

412 files changed

+9464
-12380
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

412 files changed

+9464
-12380
lines changed

analysis_options.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ analyzer:
33
exclude:
44
- lib/di/di.config.dart
55
- "**.reflectable.dart"
6+
# TODO: Enable when dependency conflict with reflectable (used in bridge) is resolved
7+
# plugins:
8+
# - custom_lint

docs/architecture.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -281,19 +281,27 @@ We use the [Elementary](https://pub.dev/packages/elementary) package as our impl
281281
- Management of stream subscriptions
282282
- Automatic disposal of all managed resources
283283

284+
**Important Naming Convention for Reactive Fields:**
285+
286+
All reactive fields in WidgetModel must follow strict naming conventions:
287+
- **All Notifier/Listenable types** must end with `State` suffix (ValueNotifier, ValueListenable, StateNotifier, ListenableState, EntityStateNotifier)
288+
- **Stream types** must end with `Stream` suffix (Stream, StreamController, BehaviorSubject)
289+
- **Private fields must match public getter names** (e.g., `_isLoadingState` for getter `isLoadingState`)
290+
284291
```dart
285-
// Creating notifiers with automatic disposal
286-
final _dataState = createNotifier<MyData>();
287-
final _loadingState = createEntityNotifier<MyData>();
288-
final _textController = createTextEditingController();
292+
// CORRECT - Following naming conventions
293+
late final _dataState = createNotifier<MyData>();
294+
StateNotifier<MyData> get dataState => _dataState;
289295
290-
// Creating a notifier from a stream
291-
final _streamData = createNotifierFromStream<MyData>(model.dataStream);
296+
late final _isLoadingState = createValueNotifier(false);
297+
ValueListenable<bool> get isLoadingState => _isLoadingState;
292298
293-
// Listening to a stream with automatic disposal
294-
disposableListen(model.events, (event) {
295-
// Handle event
296-
});
299+
late final _eventsStream = StreamController<Event>.broadcast();
300+
Stream<Event> get eventsStream => _eventsStream.stream;
301+
302+
// WRONG - Missing proper suffixes
303+
late final _data = createNotifier<MyData>(); // Should be _dataState
304+
late final _isLoading = createValueNotifier(false); // Should be _isLoadingState
297305
```
298306

299307
- `EntityStateNotifier` - A specialized StateNotifier that encapsulates a three-state model for UI data: loading, error, and content. It's designed for handling async operations and their UI states:

docs/llm/architecture_and_code_standards.instructions.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,29 @@ For each feature screen, create exactly these 3 files:
3636
- **Model**: Data handling, state management, extends `ElementaryModel`, MUST be `@injectable`
3737
- **WidgetModel**: Business logic, user interactions, MUST be `@injectable`
3838

39+
### Reactive Field Naming Convention
40+
41+
In WidgetModel files, ALL reactive fields must use proper suffixes:
42+
43+
- **All Notifier/Listenable types**: Must end with `State` suffix
44+
- Includes: `ValueNotifier`, `ValueListenable`, `StateNotifier`, `ListenableState`, `EntityStateNotifier`
45+
- Example: `isLoadingState`, `selectedTabState`, `userDataState`
46+
- **Stream types**: Must end with `Stream` suffix
47+
- Includes: `Stream`, `StreamController`, `BehaviorSubject`
48+
- Example: `eventsStream`, `dataStream`
49+
50+
**Private fields must match public getters:**
51+
52+
```dart
53+
// CORRECT
54+
late final _isLoadingState = createValueNotifier(false);
55+
ValueListenable<bool> get isLoadingState => _isLoadingState;
56+
57+
// WRONG - Private field name doesn't match getter
58+
late final _isLoading = createValueNotifier(false);
59+
ValueListenable<bool> get isLoadingState => _isLoading;
60+
```
61+
3962
### Base Class Patterns
4063

4164
The project uses two patterns for Elementary MVVM implementation:

lib/app/router/router.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class CompassRouter {
110110
/// Returns the stream with current active routes in the navigation stack.
111111
late final _currentRoutesSubject = _router.routerDelegate.asBehaviourSubject(
112112
() => _locationByUri(currentUri),
113+
sync: true, // prevent inconsistencies in RestoreSubroutesGuard
113114
);
114115

115116
Stream<Iterable<CompassBaseGoRoute>> get currentRoutesStream =>

lib/app/service/bootstrap/bootstrap_service.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ class BootstrapService {
7575
_bootstrapStepSubject.add(BootstrapSteps.completed);
7676

7777
return true;
78-
} catch (e, t) {
79-
_log.severe('init', e, t);
78+
} catch (e, st) {
79+
_log.severe('init', e, st);
80+
SentryWorker.instance.captureException(e, stackTrace: st);
8081
return false;
8182
}
8283
}

lib/app/service/connection/connection_service.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:app/app/service/service.dart';
2-
import 'package:app/di/di.dart';
32
import 'package:app/feature/messenger/domain/service/messenger_service.dart';
43
import 'package:dio/dio.dart';
54
import 'package:injectable/injectable.dart';
@@ -18,6 +17,7 @@ class ConnectionService {
1817
this._storageService,
1918
this._nekotonRepository,
2019
this._presetsConnectionService,
20+
this._messengerService,
2121
this._dio,
2222
);
2323

@@ -26,6 +26,7 @@ class ConnectionService {
2626
final ConnectionsStorageService _storageService;
2727
final NekotonRepository _nekotonRepository;
2828
final PresetsConnectionService _presetsConnectionService;
29+
final MessengerService _messengerService;
2930
final Dio _dio;
3031

3132
/// Set up selected connection.
@@ -107,7 +108,7 @@ class ConnectionService {
107108

108109
_log.finest('updateTransportByConnection completed!');
109110
} catch (e, t) {
110-
inject<MessengerService>().showConnectionError(null);
111+
_messengerService.showConnectionError(null);
111112
_log.severe('updateTransportByConnection', e, t);
112113

113114
final base = _storageService.baseConnection;

lib/app/service/localization/localization.dart

Lines changed: 0 additions & 2 deletions
This file was deleted.

lib/app/service/localization/widget/widget.dart

Lines changed: 0 additions & 1 deletion
This file was deleted.

lib/app/service/service.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export 'current_accounts_service.dart';
1212
export 'current_seed_service.dart';
1313
export 'http_clients.dart';
1414
export 'identify/identify.dart';
15-
export 'localization/localization.dart';
1615
export 'nekoton_related/nekoton_related.dart';
1716
export 'network_connection/network_connection.dart';
1817
export 'ntp_service.dart';

lib/app/view/app.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import 'package:app/app/router/router.dart';
22
import 'package:app/app/service/crash_detector/widget/crash_detector_widget.dart';
3-
import 'package:app/app/service/localization/service/supported_locale_codes.dart';
4-
import 'package:app/app/service/localization/widget/localization_service_widget.dart';
53
import 'package:app/app/view/app_wm.dart';
64
import 'package:app/core/wm/custom_wm.dart';
5+
import 'package:app/feature/localization/localization.dart';
76
import 'package:easy_localization/easy_localization.dart';
87
import 'package:flutter/material.dart';
98
import 'package:flutter_screenutil/flutter_screenutil.dart';

0 commit comments

Comments
 (0)