Skip to content

Commit

Permalink
Merge pull request #328 from mirea-ninja/release/v1.3.4
Browse files Browse the repository at this point in the history
Release v1.3.4
  • Loading branch information
0niel authored Jun 29, 2023
2 parents 71c6ef9 + 847e171 commit cf66635
Show file tree
Hide file tree
Showing 64 changed files with 2,393 additions and 701 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ flutter packages pub run build_runner build --delete-conflicting-outputs

## Конфигурация Firebase Analytics
1. Зарегистрируйте приложение в [Firebase](https://console.firebase.google.com/).
1. Выполните шаги для генерации `firebase_options.dart` файла с помощью [FlutterFire CLI](https://firebase.flutter.dev/docs/cli).
2. Firebase Analytics для Android не поддерживает Dart-only конфигурацию. Как только ваше приложение для Android будет зарегистрировано в Firebase, загрузите файл конфигурации с консоли Firebase (файл называется `google-services.json`). Добавьте этот файл в каталог `android/app`.
3. Проект готов для использования с Firebase Analytics и Crashlytics.
2. Выполните шаги для генерации `firebase_options.dart` файла с помощью [FlutterFire CLI](https://firebase.flutter.dev/docs/cli).
3. Firebase Analytics для Android не поддерживает Dart-only конфигурацию. Как только ваше приложение для Android будет зарегистрировано в Firebase, загрузите файл конфигурации с консоли Firebase (файл называется `google-services.json`). Добавьте этот файл в каталог `android/app`.
4. Проект готов для использования с Firebase Analytics и Crashlytics.

## Переменные окружения
Приложение использует переменные среды времени компиляции для хранения конфиденциальных данных, таких как ключи API и токены.
Expand Down
4 changes: 4 additions & 0 deletions lib/common/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const sentryDsn = String.fromEnvironment('SENTRY_DSN');

const lkClientId = String.fromEnvironment('LK_CLIENT_ID');
const lkClientSecret = String.fromEnvironment('LK_CLIENT_SECRET');
10 changes: 5 additions & 5 deletions lib/common/oauth.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import 'package:oauth2_client/oauth2_client.dart';
import 'package:oauth2_client/oauth2_helper.dart';
import 'package:rtu_mirea_app/common/constants.dart';

class MireaNinjaOauth2Client extends OAuth2Client {
MireaNinjaOauth2Client({
required String redirectUri,
required String customUriScheme,
}) : super(
authorizeUrl: 'https://lks.mirea.ninja/oauth/authorize',
tokenUrl: 'https://lks.mirea.ninja/oauth/token',
authorizeUrl: 'https://auth-app.mirea.ru/oauth/authorize',
tokenUrl: 'https://auth-app.mirea.ru/oauth/token',
redirectUri: redirectUri,
customUriScheme: customUriScheme,
);
Expand All @@ -29,9 +30,8 @@ class LksOauth2 {
oauth2Helper = OAuth2Helper(
oauth2Client,
grantType: OAuth2Helper.authorizationCode,
clientId: const String.fromEnvironment('LK_CLIENT_ID', defaultValue: ''),
clientSecret:
const String.fromEnvironment('LK_CLIENT_SECRET', defaultValue: ''),
clientId: lkClientId,
clientSecret: lkClientSecret,
scopes: ['profile', 'livestream', 'employees', 'attendance', 'scores'],
);
}
Expand Down
5 changes: 5 additions & 0 deletions lib/common/widget_data_init.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:developer';
import 'dart:io';

import 'package:home_widget/home_widget.dart';
import 'package:rtu_mirea_app/common/utils/calendar_utils.dart';
Expand All @@ -18,6 +19,10 @@ class WidgetDataProvider {

/// initial settings
static _init() async {
if (!(Platform.isIOS || Platform.isAndroid)) {
return;
}

await _checkWeeks();
await _checkSchedule();
_update();
Expand Down
2 changes: 1 addition & 1 deletion lib/data/datasources/user_remote.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ abstract class UserRemoteData {
}

class UserRemoteDataImpl implements UserRemoteData {
static const _apiUrl = 'https://lks.mirea.ninja/api';
static const _apiUrl = 'https://auth-app.mirea.ru/api';

final Dio httpClient;
final LksOauth2 lksOauth2;
Expand Down
11 changes: 5 additions & 6 deletions lib/firebase_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DefaultFirebaseOptions {
case TargetPlatform.linux:
break;
case TargetPlatform.windows:
break;
return windows;
}
} catch (e) {
// If we can't determine the platform, we'll just return the web options.
Expand Down Expand Up @@ -74,14 +74,13 @@ class DefaultFirebaseOptions {
iosBundleId: 'mirea.ninja.mireaapp',
);

static const FirebaseOptions macos = FirebaseOptions(
static const FirebaseOptions macos = ios;

static const FirebaseOptions windows = FirebaseOptions(
apiKey: 'AIzaSyAYZ5JlWF94jBGrcds7fSi5uMN1zmuieec',
appId: '1:510978291920:ios:dd9496a1680c72828c46d5',
appId: '1:510978291920:windows:dd9496a1680c72828c46d5',
messagingSenderId: '510978291920',
projectId: 'rtu-mirea-app',
storageBucket: 'rtu-mirea-app.appspot.com',
iosClientId:
'510978291920-31sgk97k4bifhc0ebpamk9m46om2e50r.apps.googleusercontent.com',
iosBundleId: 'mirea.ninja.mireaapp',
);
}
21 changes: 12 additions & 9 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ import 'package:rtu_mirea_app/presentation/theme.dart';
import 'package:intl/intl_standalone.dart';
import 'package:rtu_mirea_app/service_locator.dart' as dependency_injection;
import 'package:sentry_dio/sentry_dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_strategy/url_strategy.dart';
import 'common/constants.dart';
import 'presentation/app_notifier.dart';
import 'service_locator.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:provider/provider.dart';
import 'package:sentry_logging/sentry_logging.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Expand Down Expand Up @@ -67,7 +68,9 @@ Future<void> main() async {
options: DefaultFirebaseOptions.currentPlatform,
);

await FirebaseAnalytics.instance.logAppOpen();
if (Platform.isAndroid || Platform.isIOS) {
await FirebaseAnalytics.instance.logAppOpen();
}

if (kDebugMode) {
// Clear Secure Storage
Expand Down Expand Up @@ -97,8 +100,9 @@ Future<void> main() async {

await SentryFlutter.init(
(options) {
options.dsn =
const String.fromEnvironment('SENTRY_DSN', defaultValue: '');
options.dsn = sentryDsn;

options.enableAutoPerformanceTracing = true;

// Set tracesSampleRate to 0.2 to capture 20% of transactions for
// performance monitoring.
Expand Down Expand Up @@ -154,10 +158,7 @@ class App extends StatelessWidget {
BlocProvider<AboutAppBloc>(
create: (context) =>
getIt<AboutAppBloc>()..add(AboutAppGetMembers())),
BlocProvider<UserBloc>(
create: (context) =>
getIt<UserBloc>()..add(const UserEvent.started()),
),
BlocProvider<UserBloc>(create: (context) => getIt<UserBloc>()),
BlocProvider<AnnouncesBloc>(
create: (context) => getIt<AnnouncesBloc>()),
BlocProvider<EmployeeBloc>(create: (context) => getIt<EmployeeBloc>()),
Expand Down Expand Up @@ -203,7 +204,9 @@ class App extends StatelessWidget {
analytics: FirebaseAnalytics.instance,
),
AutoRouteObserver(),
SentryNavigatorObserver(),
SentryNavigatorObserver(
autoFinishAfter: const Duration(seconds: 5),
setRouteNameAsTransaction: true),
],
),
routeInformationProvider: appRouter.routeInfoProvider(),
Expand Down
6 changes: 4 additions & 2 deletions lib/presentation/bloc/app_cubit/app_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'dart:io' show Platform;
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:rtu_mirea_app/domain/entities/app_settings.dart';
import 'package:rtu_mirea_app/domain/usecases/get_app_settings.dart';
import 'package:rtu_mirea_app/domain/usecases/set_app_settings.dart';

part 'app_state.dart';

class AppCubit extends Cubit<AppState> {
Expand All @@ -16,7 +16,9 @@ class AppCubit extends Cubit<AppState> {
void checkOnboarding() async {
final settings = await getAppSettings();

if (settings.onboardingShown == false) {
final isMobileApp = Platform.isAndroid || Platform.isIOS;

if (settings.onboardingShown == false && isMobileApp) {
await setAppSettings(
SetAppSettingsParams(
AppSettings(
Expand Down
3 changes: 2 additions & 1 deletion lib/presentation/bloc/news_bloc/news_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class NewsBloc extends Bloc<NewsEvent, NewsState> {
emit(news.fold((failure) => NewsLoadError(), (r) {
List<NewsItem> newNews = List.from(oldNews)..addAll(r);
_offset += r.length;
return NewsLoaded(news: newNews, tags: tagsList);
return NewsLoaded(
news: newNews, tags: tagsList, selectedTag: _selectedTag);
}));
}
}
3 changes: 2 additions & 1 deletion lib/presentation/bloc/news_bloc/news_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class NewsLoading extends NewsState {
class NewsLoaded extends NewsState {
final List<NewsItem> news;
final List<String> tags;
final String? selectedTag;

const NewsLoaded({required this.news, required this.tags});
const NewsLoaded({required this.news, required this.tags, this.selectedTag});

@override
List<Object> get props => [news, tags];
Expand Down
7 changes: 7 additions & 0 deletions lib/presentation/bloc/nfc_pass_bloc/nfc_pass_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import 'package:rtu_mirea_app/domain/usecases/get_auth_token.dart';
import 'package:rtu_mirea_app/domain/usecases/get_nfc_passes.dart';
import 'package:rtu_mirea_app/domain/usecases/get_user_data.dart';

import '../user_bloc/user_bloc.dart';

part 'nfc_pass_event.dart';
part 'nfc_pass_state.dart';
part 'nfc_pass_bloc.freezed.dart';
Expand All @@ -27,6 +29,7 @@ class NfcPassBloc extends Bloc<NfcPassEvent, NfcPassState> {
final DeviceInfoPlugin deviceInfo;
final FetchNfcCode fetchNfcCode;
final GetUserData getUserData;
final UserBloc userBloc;

NfcPassBloc({
required this.getNfcPasses,
Expand All @@ -35,6 +38,7 @@ class NfcPassBloc extends Bloc<NfcPassEvent, NfcPassState> {
required this.getAuthToken,
required this.getUserData,
required this.fetchNfcCode,
required this.userBloc,
}) : super(const _Initial()) {
if (Platform.isAndroid) {
on<_Started>(_onStarted);
Expand Down Expand Up @@ -132,6 +136,9 @@ class NfcPassBloc extends Bloc<NfcPassEvent, NfcPassState> {
userDataRes.fold(
(failure) => studentId = null,
(userData) {
// Prevent multiple fetches of user profile data
userBloc.add(UserEvent.setAuntificatedData(user: userData));

var student = userData.students
.firstWhereOrNull((element) => element.status == 'активный');
student ??= userData.students.first;
Expand Down
12 changes: 12 additions & 0 deletions lib/presentation/bloc/user_bloc/user_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ class UserBloc extends Bloc<UserEvent, UserState> {
on<_LogOut>(_onLogOutEvent);
on<_Started>(_onGetUserDataEvent);
on<_GetUserData>(_onGetUserDataEvent);
on<_SetAuntificatedData>(_onSetAuntificatedDataEvent);
}

void _onSetAuntificatedDataEvent(
_SetAuntificatedData event,
Emitter<UserState> emit,
) async {
emit(_LogInSuccess(event.user));
}

void _setSentryUserIdentity(String id, String email, String group) {
Expand All @@ -40,6 +48,8 @@ class UserBloc extends Bloc<UserEvent, UserState> {
UserEvent event,
Emitter<UserState> emit,
) async {
if (state is _LogInSuccess) return;

// We use oauth2 to get token. So we don't need to pass login and password
// to the server. We just need to pass them to the oauth2 server.

Expand Down Expand Up @@ -87,6 +97,8 @@ class UserBloc extends Bloc<UserEvent, UserState> {
UserEvent event,
Emitter<UserState> emit,
) async {
if (state is _LogInSuccess) return;

final token = await getAuthToken();

bool loggedIn = token.isRight();
Expand Down
Loading

0 comments on commit cf66635

Please sign in to comment.