Init core module
This commit is contained in:
+124
@@ -0,0 +1,124 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.lock
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Visual Studio Code related
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Flutter repo-specific
|
||||||
|
/bin/cache/
|
||||||
|
/bin/mingit/
|
||||||
|
/dev/benchmarks/mega_gallery/
|
||||||
|
/dev/bots/.recipe_deps
|
||||||
|
/dev/bots/android_tools/
|
||||||
|
/dev/devicelab/ABresults*.json
|
||||||
|
/dev/docs/doc/
|
||||||
|
/dev/docs/flutter.docs.zip
|
||||||
|
/dev/docs/lib/
|
||||||
|
/dev/docs/pubspec.yaml
|
||||||
|
/dev/integration_tests/**/xcuserdata
|
||||||
|
/dev/integration_tests/**/Pods
|
||||||
|
/packages/flutter/coverage/
|
||||||
|
version
|
||||||
|
analysis_benchmark.json
|
||||||
|
|
||||||
|
# packages file containing multi-root paths
|
||||||
|
.packages.generated
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
**/generated_plugin_registrant.dart
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
build/
|
||||||
|
flutter_*.png
|
||||||
|
linked_*.ds
|
||||||
|
unlinked.ds
|
||||||
|
unlinked_spec.ds
|
||||||
|
|
||||||
|
# Android related
|
||||||
|
**/android/.gradle
|
||||||
|
**/android/captures/
|
||||||
|
**/android/local.properties
|
||||||
|
**/android/**/GeneratedPluginRegistrant.java
|
||||||
|
**/android/key.properties
|
||||||
|
*.jks
|
||||||
|
|
||||||
|
# iOS/XCode related
|
||||||
|
**/ios/**/*.mode1v3
|
||||||
|
**/ios/**/*.mode2v3
|
||||||
|
**/ios/**/*.moved-aside
|
||||||
|
**/ios/**/*.pbxuser
|
||||||
|
**/ios/**/*.perspectivev3
|
||||||
|
**/ios/**/*sync/
|
||||||
|
**/ios/**/.sconsign.dblite
|
||||||
|
**/ios/**/.tags*
|
||||||
|
**/ios/**/.vagrant/
|
||||||
|
**/ios/**/DerivedData/
|
||||||
|
**/ios/**/Icon?
|
||||||
|
**/ios/**/Pods/
|
||||||
|
**/ios/**/.symlinks/
|
||||||
|
**/ios/**/profile
|
||||||
|
**/ios/**/xcuserdata
|
||||||
|
**/ios/.generated/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
**/ios/Flutter/App.framework
|
||||||
|
**/ios/Flutter/Flutter.framework
|
||||||
|
**/ios/Flutter/Flutter.podspec
|
||||||
|
**/ios/Flutter/Generated.xcconfig
|
||||||
|
**/ios/Flutter/app.flx
|
||||||
|
**/ios/Flutter/app.zip
|
||||||
|
**/ios/Flutter/flutter_assets/
|
||||||
|
**/ios/Flutter/flutter_export_environment.sh
|
||||||
|
**/ios/ServiceDefinitions.json
|
||||||
|
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
**/macos/Flutter/GeneratedPluginRegistrant.swift
|
||||||
|
**/macos/Flutter/Flutter-Debug.xcconfig
|
||||||
|
**/macos/Flutter/Flutter-Release.xcconfig
|
||||||
|
**/macos/Flutter/Flutter-Profile.xcconfig
|
||||||
|
|
||||||
|
# Coverage
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# Symbols
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Exceptions to above rules.
|
||||||
|
!**/ios/**/default.mode1v3
|
||||||
|
!**/ios/**/default.mode2v3
|
||||||
|
!**/ios/**/default.pbxuser
|
||||||
|
!**/ios/**/default.perspectivev3
|
||||||
|
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||||
|
!/dev/ci/**/Gemfile.lock
|
||||||
|
|
||||||
|
#generated file
|
||||||
|
*.g.dart
|
||||||
|
messages_all.dart
|
||||||
|
messages_en.dart
|
||||||
|
messages_fr.dart
|
||||||
|
messages_messages.dart
|
||||||
|
messages_ru.dart
|
||||||
|
messages_vi.dart
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: d79295af24c3ed621c33713ecda14ad196fd9c31
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
project_type: module
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# core
|
||||||
|
|
||||||
|
Core Module
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
library core;
|
||||||
|
|
||||||
|
// Extensions
|
||||||
|
export 'presentation/extensions/color_extension.dart';
|
||||||
|
export 'presentation/extensions/url_extension.dart';
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
export 'presentation/utils/theme_utils.dart';
|
||||||
|
export 'presentation/utils/responsive_utils.dart';
|
||||||
|
export 'presentation/utils/keyboard_utils.dart';
|
||||||
|
export 'presentation/utils/style_utils.dart';
|
||||||
|
export 'presentation/extensions/list_extensions.dart';
|
||||||
|
|
||||||
|
// Views
|
||||||
|
export 'presentation/views/text/slogan_builder.dart';
|
||||||
|
export 'presentation/views/text/text_field_builder.dart';
|
||||||
|
export 'presentation/views/text/input_decoration_builder.dart';
|
||||||
|
export 'presentation/views/text/text_builder.dart';
|
||||||
|
export 'presentation/views/responsive/responsive_widget.dart';
|
||||||
|
export 'presentation/views/list/tree_view.dart';
|
||||||
|
|
||||||
|
// Resources
|
||||||
|
export 'presentation/resources/assets_paths.dart';
|
||||||
|
export 'presentation/resources/image_paths.dart';
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
export 'presentation/constants/constants_ui.dart';
|
||||||
|
export 'data/constants/constant.dart';
|
||||||
|
|
||||||
|
// Network
|
||||||
|
export 'data/network/config/authorization_interceptors.dart';
|
||||||
|
export 'data/network/config/dynamic_url_interceptors.dart';
|
||||||
|
export 'data/network/config/endpoint.dart';
|
||||||
|
export 'data/network/config/service_path.dart';
|
||||||
|
export 'data/network/dio_client.dart';
|
||||||
|
|
||||||
|
// State
|
||||||
|
export 'presentation/state/success.dart';
|
||||||
|
export 'presentation/state/failure.dart';
|
||||||
|
export 'presentation/state/app_state.dart';
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class Constant {
|
||||||
|
static const userId = '_id';
|
||||||
|
static const firstName = 'firstname';
|
||||||
|
static const lastName = 'lastname';
|
||||||
|
static const acceptHeaderDefault = 'application/json';
|
||||||
|
static const contentTypeHeaderDefault = 'application/json';
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
class AuthorizationInterceptors extends InterceptorsWrapper {
|
||||||
|
String? _authorization;
|
||||||
|
|
||||||
|
void changeAuthorization(String? userName, String? password) {
|
||||||
|
_authorization = base64Encode(utf8.encode('$userName:$password'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||||
|
if (_authorization != null) {
|
||||||
|
options.headers['Authorization'] = 'Basic $_authorization';
|
||||||
|
}
|
||||||
|
super.onRequest(options, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
class DynamicUrlInterceptors extends InterceptorsWrapper {
|
||||||
|
String? _baseUrl;
|
||||||
|
|
||||||
|
void changeBaseUrl(String? url) {
|
||||||
|
_baseUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||||
|
if (_baseUrl != null) {
|
||||||
|
options.baseUrl = _baseUrl!;
|
||||||
|
}
|
||||||
|
super.onRequest(options, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import 'package:core/data/network/config/service_path.dart';
|
||||||
|
|
||||||
|
class Endpoint {
|
||||||
|
static final ServicePath authentication = ServicePath('/api/login');
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class ServicePath {
|
||||||
|
final String path;
|
||||||
|
|
||||||
|
ServicePath(this.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ServicePathExtension on ServicePath {
|
||||||
|
String generateEndpointPath() {
|
||||||
|
return '$path';
|
||||||
|
}
|
||||||
|
|
||||||
|
String generateAuthenticationUrl(Uri? baseUrl) {
|
||||||
|
if (baseUrl == null) {
|
||||||
|
return generateEndpointPath();
|
||||||
|
} else {
|
||||||
|
return baseUrl.origin + generateEndpointPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
class DioClient {
|
||||||
|
final Dio _dio;
|
||||||
|
|
||||||
|
DioClient(this._dio);
|
||||||
|
|
||||||
|
Map<String, dynamic> getHeaders() => Map.from(_dio.options.headers);
|
||||||
|
|
||||||
|
Future<dynamic> get(
|
||||||
|
String path, {
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Options? options,
|
||||||
|
CancelToken? cancelToken,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
}) async {
|
||||||
|
return await _dio.get(
|
||||||
|
path,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: options,
|
||||||
|
cancelToken: cancelToken,
|
||||||
|
onReceiveProgress: onReceiveProgress)
|
||||||
|
.then((value) => value.data)
|
||||||
|
.catchError((error) => throw error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> post(
|
||||||
|
String path, {
|
||||||
|
data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Options? options,
|
||||||
|
CancelToken? cancelToken,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
}) async {
|
||||||
|
return await _dio.post(path,
|
||||||
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: options,
|
||||||
|
cancelToken: cancelToken,
|
||||||
|
onSendProgress: onSendProgress,
|
||||||
|
onReceiveProgress: onReceiveProgress)
|
||||||
|
.then((value) => value.data)
|
||||||
|
.catchError((error) => throw error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> delete(
|
||||||
|
String path, {
|
||||||
|
data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Options? options,
|
||||||
|
CancelToken? cancelToken,
|
||||||
|
}) async {
|
||||||
|
return await _dio.delete(
|
||||||
|
path,
|
||||||
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: options,
|
||||||
|
cancelToken: cancelToken)
|
||||||
|
.then((value) => value.data)
|
||||||
|
.catchError((error) => throw(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> put(
|
||||||
|
String path, {
|
||||||
|
data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Options? options,
|
||||||
|
CancelToken? cancelToken,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
ProgressCallback? onReceiveProgress
|
||||||
|
}) async {
|
||||||
|
return await _dio.put(
|
||||||
|
path,
|
||||||
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: options,
|
||||||
|
cancelToken: cancelToken,
|
||||||
|
onSendProgress: onSendProgress,
|
||||||
|
onReceiveProgress: onReceiveProgress)
|
||||||
|
.then((value) => value.data)
|
||||||
|
.catchError((error) => throw(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class ConstantsUI {
|
||||||
|
static const fontApp = 'CircularStd';
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import 'dart:ui' show Color;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
extension AppColor on Color {
|
||||||
|
static const primaryColor = Color(0xFF837DFF);
|
||||||
|
static const primaryDarkColor = Color(0xFF1C1C1C);
|
||||||
|
static const primaryLightColor = Color(0xFFFFFFFF);
|
||||||
|
static const baseTextColor = Color(0xFF7E869B);
|
||||||
|
static const textFieldTextColor = Color(0xFF7E869B);
|
||||||
|
static const textFieldLabelColor = Color(0xFF7E869B);
|
||||||
|
static const textFieldHintColor = Color(0xFF757575);
|
||||||
|
static const textFieldBorderColor = Color(0xfff2f1fd);
|
||||||
|
static const textFieldFocusedBorderColor = Color(0xFF837DFF);
|
||||||
|
static const textFieldErrorBorderColor = Color(0xffFF5858);
|
||||||
|
static const buttonColor = Color(0xFF837DFF);
|
||||||
|
static const appColor = Color(0xFF3840F7);
|
||||||
|
static const nameUserColor = Color(0xFF182952);
|
||||||
|
static const emailUserColor = Color(0xFF7E869B);
|
||||||
|
static const userInformationBackgroundColor = Color(0xFFF5F5F7);
|
||||||
|
static const searchBorderColor = Color(0xFFEAEAEA);
|
||||||
|
static const searchHintTextColor = Color(0xFF7E869B);
|
||||||
|
static const mailboxSelectedBackgroundColor = Color(0xFFE6E5FF);
|
||||||
|
static const mailboxBackgroundColor = Color(0xFFFFFFFF);
|
||||||
|
static const mailboxSelectedTextColor = Color(0xFF3840F7);
|
||||||
|
static const mailboxTextColor = Color(0xFF182952);
|
||||||
|
static const mailboxSelectedTextNumberColor = Color(0xFF182952);
|
||||||
|
static const mailboxTextNumberColor = Color(0xFF837DFF);
|
||||||
|
static const mailboxSelectedIconColor = Color(0xFF3840F7);
|
||||||
|
static const mailboxIconColor = Color(0xFF7E869B);
|
||||||
|
static const storageBackgroundColor = Color(0xFFF5F5F7);
|
||||||
|
static const storageTitleColor = Color(0xFF7E869B);
|
||||||
|
static const storageMaxSizeColor = Color(0xFF101D43);
|
||||||
|
static const storageUseSizeColor = Color(0xFF2D0CFF);
|
||||||
|
static const myFolderTitleColor = Color(0xFF7E869B);
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:built_collection/built_collection.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
|
extension ListExtensions<T> on List<T> {
|
||||||
|
Tuple2<List<T>, List<T>> split(bool test(T element)) {
|
||||||
|
final validBuilder = ListBuilder<T>();
|
||||||
|
final invalidBuilder = ListBuilder<T>();
|
||||||
|
forEach((element) {
|
||||||
|
if (test(element)) {
|
||||||
|
validBuilder.add(element);
|
||||||
|
} else {
|
||||||
|
invalidBuilder.add(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return Tuple2(
|
||||||
|
validBuilder.build().toList(),
|
||||||
|
validBuilder.build().toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
extension URLExtension on String {
|
||||||
|
static final String prefixUrlHttps = 'https://';
|
||||||
|
static final String prefixUrlHttp = 'http://';
|
||||||
|
|
||||||
|
String formatURLValid() {
|
||||||
|
if (startsWith(prefixUrlHttps)) {
|
||||||
|
return this;
|
||||||
|
} else if (startsWith(prefixUrlHttp)) {
|
||||||
|
return kReleaseMode ? replaceAll(prefixUrlHttp, prefixUrlHttps) : this;
|
||||||
|
} else {
|
||||||
|
return '$prefixUrlHttps${this}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class AssetsPaths {
|
||||||
|
static const images = 'assets/images/';
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:core/presentation/resources/assets_paths.dart';
|
||||||
|
|
||||||
|
class ImagePaths {
|
||||||
|
String get icTMailLogo => _getImagePath('tmail_logo.svg');
|
||||||
|
String get icCloseMailbox => _getImagePath('ic_close.svg');
|
||||||
|
String get icSearch => _getImagePath('ic_search.svg');
|
||||||
|
String get icNextArrow => _getImagePath('ic_next_arrow.svg');
|
||||||
|
String get icMailboxInbox => _getImagePath('ic_mailbox_inbox.svg');
|
||||||
|
String get icMailboxTrash => _getImagePath('ic_mailbox_trash.svg');
|
||||||
|
String get icMailboxAllMail => _getImagePath('ic_mailbox_allmail.svg');
|
||||||
|
String get icMailboxDrafts => _getImagePath('ic_mailbox_draft.svg');
|
||||||
|
String get icMailboxSent => _getImagePath('ic_mailbox_sent.svg');
|
||||||
|
String get icMailboxSpam => _getImagePath('ic_mailbox_spam.svg');
|
||||||
|
String get icMailboxTemplate => _getImagePath('ic_mailbox_template.svg');
|
||||||
|
String get icMailboxFolder => _getImagePath('ic_mailbox_folder.svg');
|
||||||
|
String get icMailboxNewFolder => _getImagePath('ic_mailbox_new_folder.svg');
|
||||||
|
String get icFolderArrow => _getImagePath('ic_folder_arrow.svg');
|
||||||
|
String get icExpandFolder => _getImagePath('ic_expand_folder.svg');
|
||||||
|
|
||||||
|
String _getImagePath(String imageName) {
|
||||||
|
return AssetsPaths.images + imageName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import 'package:core/core.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class AppState with EquatableMixin {
|
||||||
|
final Either<Failure, Success> viewState;
|
||||||
|
|
||||||
|
AppState(this.viewState);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [viewState];
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
abstract class Failure extends Equatable {}
|
||||||
|
|
||||||
|
abstract class FeatureFailure extends Failure {}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
abstract class Success with EquatableMixin {}
|
||||||
|
|
||||||
|
abstract class ViewState extends Success {}
|
||||||
|
|
||||||
|
class UIState extends ViewState {
|
||||||
|
static final idle = UIState();
|
||||||
|
static final loading = UIState();
|
||||||
|
|
||||||
|
UIState() : super();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
class KeyboardUtils {
|
||||||
|
void hideKeyboard(BuildContext context) {
|
||||||
|
FocusScopeNode currentFocus = FocusScope.of(context);
|
||||||
|
if (!currentFocus.hasPrimaryFocus) {
|
||||||
|
currentFocus.unfocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class ResponsiveUtils {
|
||||||
|
|
||||||
|
static const int _minLargeWidth = 950;
|
||||||
|
static const int _minMediumWidth = 600;
|
||||||
|
|
||||||
|
static const double _loginTextFieldWidthSmallScreen = 280.0;
|
||||||
|
static const double _loginTextFieldWidthLargeScreen = 320.0;
|
||||||
|
static const double _loginButtonWidth = 240.0;
|
||||||
|
|
||||||
|
double getSizeWidthScreen(BuildContext context) {
|
||||||
|
return MediaQuery.of(context).size.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getSizeHeightScreen(BuildContext context) {
|
||||||
|
return MediaQuery.of(context).size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLargeScreen(BuildContext context) {
|
||||||
|
return getSizeWidthScreen(context) >= _minLargeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSmallScreen(BuildContext context) {
|
||||||
|
return getSizeWidthScreen(context) < _minMediumWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMediumScreen(BuildContext context) {
|
||||||
|
return getSizeWidthScreen(context) >= _minMediumWidth && getSizeWidthScreen(context) < _minLargeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getWidthLoginTextField(BuildContext context) => isSmallScreen(context)
|
||||||
|
? _loginTextFieldWidthSmallScreen
|
||||||
|
: _loginTextFieldWidthLargeScreen;
|
||||||
|
|
||||||
|
double getWidthLoginButton() => _loginButtonWidth;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CommonTextStyle {
|
||||||
|
static final textStyleNormal = TextStyle(
|
||||||
|
color: AppColor.primaryColor,
|
||||||
|
fontSize: 14,
|
||||||
|
fontStyle: FontStyle.normal,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import 'package:core/presentation/constants/constants_ui.dart';
|
||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
ThemeData appTheme() {
|
||||||
|
return ThemeData(
|
||||||
|
scaffoldBackgroundColor: Colors.white,
|
||||||
|
fontFamily: ConstantsUI.fontApp,
|
||||||
|
appBarTheme: appBarTheme(),
|
||||||
|
textTheme: textTheme(),
|
||||||
|
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationTheme inputDecorationTheme() {
|
||||||
|
OutlineInputBorder outlineInputBorder = OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(28),
|
||||||
|
borderSide: BorderSide(color: AppColor.baseTextColor),
|
||||||
|
gapPadding: 10,
|
||||||
|
);
|
||||||
|
return InputDecorationTheme(
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 42, vertical: 20),
|
||||||
|
enabledBorder: outlineInputBorder,
|
||||||
|
focusedBorder: outlineInputBorder,
|
||||||
|
border: outlineInputBorder,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextTheme textTheme() {
|
||||||
|
return TextTheme(
|
||||||
|
bodyText1: TextStyle(color: AppColor.baseTextColor),
|
||||||
|
bodyText2: TextStyle(color: AppColor.baseTextColor),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
AppBarTheme appBarTheme() {
|
||||||
|
return AppBarTheme(
|
||||||
|
color: Colors.white,
|
||||||
|
elevation: 0,
|
||||||
|
brightness: Brightness.light,
|
||||||
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
|
textTheme: TextTheme(
|
||||||
|
headline6: TextStyle(color: Color(0XFF8B8B8B), fontSize: 18),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
|
||||||
|
class TreeView extends InheritedWidget {
|
||||||
|
final List<Widget> children;
|
||||||
|
final bool startExpanded;
|
||||||
|
|
||||||
|
TreeView({
|
||||||
|
Key? key,
|
||||||
|
required List<Widget> children,
|
||||||
|
bool startExpanded = false,
|
||||||
|
}) : this.children = children, this.startExpanded = startExpanded, super (
|
||||||
|
key: key,
|
||||||
|
child: _TreeViewData(
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
static TreeView of(BuildContext context) {
|
||||||
|
return context.dependOnInheritedWidgetOfExactType<TreeView>()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool updateShouldNotify(TreeView oldWidget) {
|
||||||
|
if (oldWidget.children == this.children &&
|
||||||
|
oldWidget.startExpanded == this.startExpanded) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TreeViewData extends StatelessWidget {
|
||||||
|
final List<Widget> children;
|
||||||
|
|
||||||
|
const _TreeViewData({
|
||||||
|
required this.children,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
primary: false,
|
||||||
|
itemCount: children.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return children.elementAt(index);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreeViewChild extends StatefulWidget {
|
||||||
|
final bool? startExpanded;
|
||||||
|
final Widget parent;
|
||||||
|
final List<Widget> children;
|
||||||
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
|
TreeViewChild({
|
||||||
|
required this.parent,
|
||||||
|
required this.children,
|
||||||
|
this.startExpanded,
|
||||||
|
this.onTap,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
TreeViewChildState createState() => TreeViewChildState();
|
||||||
|
|
||||||
|
TreeViewChild copyWith(
|
||||||
|
TreeViewChild source, {
|
||||||
|
bool? startExpanded,
|
||||||
|
Widget? parent,
|
||||||
|
List<Widget>? children,
|
||||||
|
VoidCallback? onTap,
|
||||||
|
}) {
|
||||||
|
return TreeViewChild(
|
||||||
|
parent: parent ?? source.parent,
|
||||||
|
children: children ?? source.children,
|
||||||
|
startExpanded: startExpanded ?? source.startExpanded,
|
||||||
|
onTap: onTap ?? source.onTap,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreeViewChildState extends State<TreeViewChild> {
|
||||||
|
bool? isExpanded;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
isExpanded = widget.startExpanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
isExpanded = widget.startExpanded ?? TreeView.of(context).startExpanded;
|
||||||
|
super.didChangeDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
GestureDetector(
|
||||||
|
child: widget.parent,
|
||||||
|
onTap: () {
|
||||||
|
if (widget.onTap != null) {
|
||||||
|
widget.onTap!();
|
||||||
|
}
|
||||||
|
toggleExpanded();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
AnimatedContainer(
|
||||||
|
duration: Duration(milliseconds: 400),
|
||||||
|
child: isExpanded!
|
||||||
|
? Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: widget.children,
|
||||||
|
)
|
||||||
|
: Offstage(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleExpanded() {
|
||||||
|
setState(() {
|
||||||
|
this.isExpanded = !this.isExpanded!;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ResponsiveWidget extends StatelessWidget {
|
||||||
|
final Widget? largeScreen;
|
||||||
|
final Widget mediumScreen;
|
||||||
|
final Widget? smallScreen;
|
||||||
|
|
||||||
|
final ResponsiveUtils responsiveUtils;
|
||||||
|
|
||||||
|
const ResponsiveWidget({
|
||||||
|
Key? key,
|
||||||
|
this.largeScreen,
|
||||||
|
required this.mediumScreen,
|
||||||
|
this.smallScreen,
|
||||||
|
required this.responsiveUtils,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
|
if (responsiveUtils.isLargeScreen(context)) {
|
||||||
|
return largeScreen ?? mediumScreen;
|
||||||
|
} else if (responsiveUtils.isMediumScreen(context)) {
|
||||||
|
return mediumScreen;
|
||||||
|
} else {
|
||||||
|
return smallScreen ?? mediumScreen;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
abstract class InputDecorationBuilder {
|
||||||
|
String? prefixText;
|
||||||
|
String? labelText;
|
||||||
|
TextStyle? labelStyle;
|
||||||
|
String? hintText;
|
||||||
|
TextStyle? hintStyle;
|
||||||
|
EdgeInsets? contentPadding;
|
||||||
|
OutlineInputBorder? enabledBorder;
|
||||||
|
|
||||||
|
InputDecorationBuilder setPrefixText(String newPrefixText) {
|
||||||
|
prefixText = newPrefixText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationBuilder setLabelText(String newLabelText) {
|
||||||
|
labelText = newLabelText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationBuilder setLabelStyle(TextStyle newLabelStyle) {
|
||||||
|
labelStyle = newLabelStyle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationBuilder setHintText(String newHintText) {
|
||||||
|
hintText = newHintText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationBuilder setHintStyle(TextStyle newHintStyle) {
|
||||||
|
hintStyle = newHintStyle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationBuilder setContentPadding(EdgeInsets newContentPadding) {
|
||||||
|
contentPadding = newContentPadding;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecorationBuilder setEnabledBorder(OutlineInputBorder newEnabledBorder) {
|
||||||
|
enabledBorder = newEnabledBorder;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDecoration build() {
|
||||||
|
return InputDecoration(
|
||||||
|
prefixText: prefixText,
|
||||||
|
labelText: labelText,
|
||||||
|
labelStyle: labelStyle,
|
||||||
|
hintText: hintText,
|
||||||
|
hintStyle: hintStyle,
|
||||||
|
contentPadding: contentPadding,
|
||||||
|
enabledBorder: enabledBorder);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
|
/// A builder which builds a reusable slogan widget.
|
||||||
|
/// This contains the logo and the slogan text.
|
||||||
|
/// The elements are arranged in a column.
|
||||||
|
class SloganBuilder {
|
||||||
|
Key? _key;
|
||||||
|
String? _text;
|
||||||
|
TextStyle? _textStyle;
|
||||||
|
TextAlign? _textAlign;
|
||||||
|
String? _logo;
|
||||||
|
|
||||||
|
SloganBuilder key(Key key) {
|
||||||
|
_key = key;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SloganBuilder setSloganText(String text) {
|
||||||
|
_text = text;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SloganBuilder setSloganTextStyle(TextStyle textStyle) {
|
||||||
|
_textStyle = textStyle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SloganBuilder setSloganTextAlign(TextAlign textAlign) {
|
||||||
|
_textAlign = textAlign;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SloganBuilder setLogo(String logo) {
|
||||||
|
_logo = logo;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget build() {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
_logo != null ? SvgPicture.asset(_logo!, width: 150, height: 150) : SizedBox.shrink(),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 16, left: 16, right: 16),
|
||||||
|
child: Text(_text ?? '', key: _key, style: _textStyle, textAlign: _textAlign),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:core/presentation/utils/style_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TextBuilder {
|
||||||
|
String? _text;
|
||||||
|
TextStyle? _textStyle;
|
||||||
|
TextAlign? _textAlign;
|
||||||
|
Key? _key;
|
||||||
|
|
||||||
|
TextBuilder key(Key key) {
|
||||||
|
_key = key;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBuilder text(String text) {
|
||||||
|
_text = text;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBuilder textStyle(TextStyle textStyle) {
|
||||||
|
_textStyle = textStyle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBuilder textAlign(TextAlign textAlign) {
|
||||||
|
_textAlign = textAlign;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text build() {
|
||||||
|
return Text(_text ?? '', key: _key ?? Key('TextBuilder'), style: _textStyle ?? CommonTextStyle.textStyleNormal, textAlign: _textAlign ?? TextAlign.center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CenterTextBuilder extends TextBuilder {
|
||||||
|
@override
|
||||||
|
Text build() {
|
||||||
|
return Text(_text ?? '', key: _key ?? Key('TextBuilder'), style: _textStyle, textAlign: TextAlign.center);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TextFieldBuilder {
|
||||||
|
Key? _key;
|
||||||
|
ValueChanged<String>? _onTextChange;
|
||||||
|
TextStyle? _textStyle;
|
||||||
|
TextInputAction? _textInputAction;
|
||||||
|
InputDecoration? _inputDecoration;
|
||||||
|
bool? _obscureText;
|
||||||
|
|
||||||
|
TextFieldBuilder key(Key key) {
|
||||||
|
_key = key;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBuilder onChange(ValueChanged<String> onChange) {
|
||||||
|
_onTextChange = onChange;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBuilder textStyle(TextStyle style) {
|
||||||
|
_textStyle = style;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBuilder textInputAction(TextInputAction inputAction) {
|
||||||
|
_textInputAction = inputAction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBuilder textDecoration(InputDecoration inputDecoration) {
|
||||||
|
_inputDecoration = inputDecoration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBuilder obscureText(bool obscureText) {
|
||||||
|
_obscureText = obscureText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField build() {
|
||||||
|
return TextField(
|
||||||
|
key: _key ?? Key('TextFieldBuilder'),
|
||||||
|
onChanged: _onTextChange,
|
||||||
|
cursorColor: AppColor.primaryColor,
|
||||||
|
textInputAction: _textInputAction,
|
||||||
|
decoration: _inputDecoration,
|
||||||
|
style: _textStyle ?? TextStyle(color: AppColor.textFieldTextColor),
|
||||||
|
obscureText: _obscureText ?? false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
name: core
|
||||||
|
description: Core Module
|
||||||
|
|
||||||
|
# The following defines the version and build number for your application.
|
||||||
|
# A version number is three numbers separated by dots, like 1.2.43
|
||||||
|
# followed by an optional build number separated by a +.
|
||||||
|
# Both the version and the builder number may be overridden in flutter
|
||||||
|
# build by specifying --build-name and --build-number, respectively.
|
||||||
|
# In Android, build-name is used as versionName while build-number used as versionCode.
|
||||||
|
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
||||||
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
|
# Read more about iOS versioning at
|
||||||
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
|
#
|
||||||
|
# This version is used _only_ for the Runner app, which is used if you just do
|
||||||
|
# a `flutter run` or a `flutter make-host-app-editable`. It has no impact
|
||||||
|
# on any other native host app that you embed your Flutter project into.
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# The following adds the Cupertino Icons font to your application.
|
||||||
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
cupertino_icons: ^1.0.2
|
||||||
|
|
||||||
|
# flutter_svg
|
||||||
|
flutter_svg: 0.22.0
|
||||||
|
|
||||||
|
# Http client
|
||||||
|
dio: 4.0.0
|
||||||
|
|
||||||
|
# dartz
|
||||||
|
dartz: 0.10.0-nullsafety.2
|
||||||
|
|
||||||
|
# equatable
|
||||||
|
equatable: 2.0.3
|
||||||
|
|
||||||
|
built_collection: 5.1.0
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
build_runner: 2.0.5
|
||||||
|
# For information on the generic Dart part of this file, see the
|
||||||
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
# The following line ensures that the Material Icons font is
|
||||||
|
# included with your application, so that you can use the icons in
|
||||||
|
# the material Icons class.
|
||||||
|
uses-material-design: true
|
||||||
|
|
||||||
|
# To add Flutter specific assets to your application, add an assets section,
|
||||||
|
# like this:
|
||||||
|
# assets:
|
||||||
|
# - images/a_dot_burr.jpeg
|
||||||
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||||
|
|
||||||
|
# For details regarding adding assets from package dependencies, see
|
||||||
|
# https://flutter.dev/assets-and-images/#from-packages
|
||||||
|
|
||||||
|
# To add Flutter specific custom fonts to your application, add a fonts
|
||||||
|
# section here, in this "flutter" section. Each entry in this list should
|
||||||
|
# have a "family" key with the font family name, and a "fonts" key with a
|
||||||
|
# list giving the asset and other descriptors for the font. For
|
||||||
|
# example:
|
||||||
|
# fonts:
|
||||||
|
# - family: Schyler
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/Schyler-Regular.ttf
|
||||||
|
# - asset: fonts/Schyler-Italic.ttf
|
||||||
|
# style: italic
|
||||||
|
# - family: Trajan Pro
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/TrajanPro.ttf
|
||||||
|
# - asset: fonts/TrajanPro_Bold.ttf
|
||||||
|
# weight: 700
|
||||||
|
#
|
||||||
|
# For details regarding fonts from package dependencies,
|
||||||
|
# see https://flutter.dev/custom-fonts/#from-packages
|
||||||
|
|
||||||
|
|
||||||
|
# This section identifies your Flutter project as a module meant for
|
||||||
|
# embedding in a native host app. These identifiers should _not_ ordinarily
|
||||||
|
# be changed after generation - they are used to ensure that the tooling can
|
||||||
|
# maintain consistency when adding or modifying assets and plugins.
|
||||||
|
# They also do not have any bearing on your native host application's
|
||||||
|
# identifiers, which may be completely independent or the same as these.
|
||||||
Reference in New Issue
Block a user