Skip to content

Commit

Permalink
Использование GitHub для скачивания загрузочных экранов (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
Namxobick authored Sep 23, 2024
1 parent 1e82b76 commit f85c084
Show file tree
Hide file tree
Showing 18 changed files with 553 additions and 23 deletions.
17 changes: 13 additions & 4 deletions lib/core/constants/api_url_strings.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
class ApiPaths {
/// Доменное имя
static const String host = 'portal.unn.ru';
/// Доменное имя gitHub
static const String gitHubHost = 'raw.githubusercontent.com';

/// Второе доменное имя
static const String mobileHost = 'portal-m.unn.ru';
/// Доменное имя api gitHub
static const String gitHubApiHost = 'api.github.com';

/// Доменное имя unn портала
static const String unnHost = 'portal.unn.ru';

/// Второе доменное имя unn портала
static const String unnMobileHost = 'portal-m.unn.ru';

/// Для доступа к репозиторию с загрузочными экранами
static const String gitRepository = 'BitCodersNN/unn-mobile.loading-screen';

/// Для авторизация
static const String auth = 'auth/';
Expand Down
3 changes: 1 addition & 2 deletions lib/core/misc/http_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class HttpRequestSender {

HttpRequestSender({
bool useSSL = true,
String host = ApiPaths.host,
String host = ApiPaths.unnHost,
required String path,
Map<String, dynamic> queryParams = const {},
Map<String, String> headers = const {},
Expand Down Expand Up @@ -88,7 +88,6 @@ class HttpRequestSender {
int timeoutSeconds,
) async {
final httpClient = HttpClient();

final request = await httpClient.openUrl(method.name, _createURI()).timeout(
Duration(seconds: timeoutSeconds),
onTimeout: () => throw TimeoutException('Open url timed out'),
Expand Down
138 changes: 129 additions & 9 deletions lib/core/models/loading_page_data.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
import 'package:flutter/material.dart';

class _KeysForLoadingPageModelJsonConverter {
static const String logoPath = 'logo_path';
static const String startDate = 'start_date';
static const String endDate = 'end_date';
static const String title = 'title';
static const String description = 'description';
static const String text = 'text';
static const String color = 'color';
static const String fontSize = 'fontSize';
}

class LoadingPageModel {
static const defaultTextStyle = TextStyle(
color: Color(0xFF0F68AA),
fontSize: 34.09,
fontFamily: 'LetoSans',
);

static const defaultTitle = 'УНИВЕРСИТЕТ \n ЛОБАЧЕВСКОГО';

final String _imagePath;
final DateTimeRange? _dateTimeRangeToUseOn;
final String _title;
final TextStyle _titleStyle;
final String _imagePath;
final String? _description;
final TextStyle? _descriptionStyle;

LoadingPageModel({
String title = 'УНИВЕРСИТЕТ \n ЛОБАЧЕВСКОГО',
TextStyle titleStyle = const TextStyle(
color: Color(0xFF0F68AA),
fontSize: 34.09,
fontFamily: 'LetoSans',
),
required String imagePath,
DateTimeRange? dateTimeRangeToUseOn,
String title = defaultTitle,
TextStyle titleStyle = defaultTextStyle,
String? description,
TextStyle? descriptionStyle,
}) : _title = title,
}) : _imagePath = imagePath,
_dateTimeRangeToUseOn = dateTimeRangeToUseOn,
_title = title,
_titleStyle = titleStyle,
_imagePath = imagePath,
_description = description,
_descriptionStyle = descriptionStyle;

Expand All @@ -28,4 +46,106 @@ class LoadingPageModel {
String? get description => _description;
TextStyle get titleStyle => _titleStyle;
TextStyle? get descriptionStyle => _descriptionStyle;

factory LoadingPageModel.fromJson(Map<String, dynamic> json) {
final String imagePath =
json[_KeysForLoadingPageModelJsonConverter.logoPath];

final DateTimeRange? dateTimeRange = _getDateTimeRangeFromJson(json);

final titleJson = json[_KeysForLoadingPageModelJsonConverter.title];
final String title =
titleJson?[_KeysForLoadingPageModelJsonConverter.text] ?? defaultTitle;
final titleStyle = _getTextStyleFromJson(titleJson) ?? defaultTextStyle;

final descriptionJson =
json[_KeysForLoadingPageModelJsonConverter.description];
final String? description =
descriptionJson?[_KeysForLoadingPageModelJsonConverter.text];

final descriptionStyle = _getTextStyleFromJson(descriptionJson);

return LoadingPageModel(
imagePath: imagePath,
dateTimeRangeToUseOn: dateTimeRange,
title: title,
titleStyle: titleStyle,
description: description,
descriptionStyle: descriptionStyle,
);
}

static DateTimeRange? _getDateTimeRangeFromJson(Map<String, dynamic> json) {
final String? startDateStr =
json[_KeysForLoadingPageModelJsonConverter.startDate];
final String? endDateStr =
json[_KeysForLoadingPageModelJsonConverter.endDate];

DateTimeRange? dateTimeRange;
if (startDateStr != null && endDateStr != null) {
final now = DateTime.now();
final yearString = now.year.toString();

final startDate = DateTime.parse('$yearString-$startDateStr');
final endDate = DateTime.parse('$yearString-$endDateStr');
dateTimeRange = DateTimeRange(start: startDate, end: endDate);
}

return dateTimeRange;
}

static TextStyle? _getTextStyleFromJson(
Map<String, dynamic>? json, {
TextStyle defaultTextStyle = defaultTextStyle,
}) {
if (json == null) {
return null;
}

final colorFromJson = json[_KeysForLoadingPageModelJsonConverter.color];
final colorInt = int.tryParse(
colorFromJson ?? defaultTextStyle.color.toString(),
);
final Color titleColor = Color(colorInt!);

final fontSizeFromJson =
json[_KeysForLoadingPageModelJsonConverter.fontSize];

final fontSize = double.tryParse(
fontSizeFromJson ?? defaultTextStyle.fontSize.toString(),
);

final TextStyle titleStyle = TextStyle(
color: titleColor,
fontSize: fontSize,
fontFamily: defaultTextStyle.fontFamily,
);

return titleStyle;
}

Map<String, dynamic> toJson() {
return {
_KeysForLoadingPageModelJsonConverter.logoPath: _imagePath,
_KeysForLoadingPageModelJsonConverter.startDate:
_dateTimeRangeToUseOn?.start.toString().substring(5, 10),
_KeysForLoadingPageModelJsonConverter.endDate:
_dateTimeRangeToUseOn?.end.toString().substring(5, 10),
_KeysForLoadingPageModelJsonConverter.title: {
_KeysForLoadingPageModelJsonConverter.text: _title,
_KeysForLoadingPageModelJsonConverter.color:
_titleStyle.color!.value.toRadixString(16),
_KeysForLoadingPageModelJsonConverter.fontSize:
_titleStyle.fontSize.toString(),
},
if (_description != null)
_KeysForLoadingPageModelJsonConverter.description: {
_KeysForLoadingPageModelJsonConverter.text: _description,
_KeysForLoadingPageModelJsonConverter.color:
_descriptionStyle?.color!.value.toRadixString(16),
_KeysForLoadingPageModelJsonConverter.fontSize:
_descriptionStyle?.fontSize.toString(),
},
};
}
}
22 changes: 15 additions & 7 deletions lib/core/services/implementations/authorisation_service_impl.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import 'dart:io';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:unn_mobile/core/constants/api_url_strings.dart';
import 'package:unn_mobile/core/constants/session_identifier_strings.dart';
import 'package:unn_mobile/core/misc/http_helper.dart';
import 'package:unn_mobile/core/models/online_status_data.dart';
import 'package:unn_mobile/core/services/interfaces/authorisation_service.dart';
import 'package:unn_mobile/core/services/interfaces/logger_service.dart';

class AuthorizationServiceImpl implements AuthorizationService {
class AuthorizationServiceImpl extends ChangeNotifier
implements AuthorizationService {
final OnlineStatusData _onlineStatus;
final LoggerService _loggerService;
final String _userLogin = 'USER_LOGIN';
Expand Down Expand Up @@ -44,7 +44,7 @@ class AuthorizationServiceImpl implements AuthorizationService {
}

final requestSender = HttpRequestSender(
host: ApiPaths.mobileHost,
host: ApiPaths.unnMobileHost,
path: ApiPaths.authWithCookie,
);

Expand Down Expand Up @@ -80,10 +80,13 @@ class AuthorizationServiceImpl implements AuthorizationService {
return AuthRequestResult.unknown;
}

_sessionId = _extractValue(
responseString,
SessionIdentifierStrings.sessionIdCookieKey,
_setSessionId(
_extractValue(
responseString,
SessionIdentifierStrings.sessionIdCookieKey,
),
);

_guestId = _extractValue(responseString, _bxPortatlUnnGuestId);
_csrf = _extractValue(responseString, SessionIdentifierStrings.csrf);
_isAuthorised = true;
Expand All @@ -94,6 +97,11 @@ class AuthorizationServiceImpl implements AuthorizationService {
return AuthRequestResult.success;
}

void _setSessionId(String newSessionId) {
_sessionId = newSessionId;
notifyListeners();
}

String _extractValue(String input, String key) {
final RegExp regExp = RegExp('$key=([^;]+)');
final Match? match = regExp.firstMatch(input);
Expand Down
31 changes: 31 additions & 0 deletions lib/core/services/implementations/feed_file_downloader_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:unn_mobile/core/constants/api_url_strings.dart';
import 'package:unn_mobile/core/constants/session_identifier_strings.dart';
import 'package:unn_mobile/core/services/implementations/authorisation_service_impl.dart';
import 'package:unn_mobile/core/services/interfaces/base_file_downloader.dart';
import 'package:unn_mobile/core/services/interfaces/logger_service.dart';

class FeedFileDownloaderImpl extends BaseFileDownloaderService {
final AuthorizationServiceImpl _authorisationService;
FeedFileDownloaderImpl(
LoggerService loggerService,
AuthorizationServiceImpl authorisationService,
) : _authorisationService = authorisationService,
super(
loggerService,
ApiPaths.unnHost,
cookies: {
SessionIdentifierStrings.sessionIdCookieKey:
authorisationService.sessionId ?? '',
},
) {
_authorisationService.addListener(_updateCookies);
}

void _updateCookies() {
final newCookie = {
SessionIdentifierStrings.sessionIdCookieKey:
_authorisationService.sessionId ?? '',
};
super.updateCookies(newCookie);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'dart:convert';
import 'dart:io';

import 'package:unn_mobile/core/constants/api_url_strings.dart';
import 'package:unn_mobile/core/misc/http_helper.dart';
import 'package:unn_mobile/core/services/interfaces/loading_page/last_commit_sha.dart';
import 'package:unn_mobile/core/services/interfaces/logger_service.dart';

class LastCommitShaImpl implements LastCommitShaService {
final _path = 'repos/${ApiPaths.gitRepository}/commits/main?per_page=1';
final LoggerService _loggerService;

LastCommitShaImpl(this._loggerService);

@override
Future<String?> getSha() async {
final requestSender = HttpRequestSender(
host: ApiPaths.gitHubApiHost,
path: _path,
);

HttpClientResponse response;
try {
response = await requestSender.get();
} catch (error, stackTrace) {
_loggerService.log('Exception: $error\nStackTrace: $stackTrace');
return null;
}

final statusCode = response.statusCode;

if (statusCode != 200) {
_loggerService.log(
'statusCode = $statusCode;',
);
return null;
}

Map<String, dynamic> jsonMap;

try {
jsonMap =
jsonDecode(await HttpRequestSender.responseToStringBody(response));
} catch (error, stackTrace) {
_loggerService.logError(error, stackTrace);
return null;
}

return jsonMap['sha'];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:unn_mobile/core/services/interfaces/loading_page/last_commit_sha_provider.dart';
import 'package:unn_mobile/core/services/interfaces/storage_service.dart';

class _LastCommitShaKeys {
static const shaKey = 'sha_key';
}

class LastCommitShaProviderImpl implements LastCommitShaProvider {
final StorageService _storage;

LastCommitShaProviderImpl(this._storage);

@override
Future<String?> getData() async {
if (!(await isContained())) {
return null;
}

final sha = await _storage.read(
key: _LastCommitShaKeys.shaKey,
);

return sha;
}

@override
Future<void> saveData(String? sha) async {
if (sha == null) {
return;
}

await _storage.write(
key: _LastCommitShaKeys.shaKey,
value: sha,
);
}

@override
Future<bool> isContained() async {
return await _storage.containsKey(
key: _LastCommitShaKeys.shaKey,
);
}
}
Loading

0 comments on commit f85c084

Please sign in to comment.