forked from kherel/selfprivacy.org.app
parent
cd02c75e2f
commit
90df52e895
Binary file not shown.
@ -0,0 +1,21 @@ |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_bloc/flutter_bloc.dart'; |
||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; |
||||
|
||||
class BlocAndProviderConfig extends StatelessWidget { |
||||
const BlocAndProviderConfig({Key key, this.child}) : super(key: key); |
||||
|
||||
final Widget child; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return MultiProvider( |
||||
providers: [ |
||||
BlocProvider<ServicesCubit>( |
||||
create: (BuildContext context) => ServicesCubit(), |
||||
), |
||||
], |
||||
child: child, |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,24 @@ |
||||
import 'package:bloc/bloc.dart'; |
||||
import 'package:meta/meta.dart'; |
||||
import 'package:selfprivacy/logic/models/service.dart'; |
||||
export 'package:provider/provider.dart'; |
||||
|
||||
part 'services_state.dart'; |
||||
|
||||
class ServicesCubit extends Cubit<ServicesState> { |
||||
ServicesCubit() : super(ServicesState(all)); |
||||
|
||||
void connect(Service service) { |
||||
var newState = state.updateElement(service, ServiceStateType.stable); |
||||
emit(newState); |
||||
} |
||||
} |
||||
|
||||
final all = ServiceTypes.values |
||||
.map( |
||||
(type) => Service( |
||||
state: ServiceStateType.uninitialized, |
||||
type: type, |
||||
), |
||||
) |
||||
.toList(); |
@ -0,0 +1,23 @@ |
||||
part of 'services_cubit.dart'; |
||||
|
||||
@immutable |
||||
class ServicesState { |
||||
ServicesState(this.all); |
||||
|
||||
final List<Service> all; |
||||
|
||||
ServicesState updateElement(Service service, ServiceStateType newState) { |
||||
var newList = [...all]; |
||||
var index = newList.indexOf(service); |
||||
newList[index] = service.updateState(newState); |
||||
return ServicesState(newList); |
||||
} |
||||
|
||||
List<Service> get connected => all |
||||
.where((service) => service.state != ServiceStateType.uninitialized) |
||||
.toList(); |
||||
|
||||
List<Service> get uninitialized => all |
||||
.where((service) => service.state == ServiceStateType.uninitialized) |
||||
.toList(); |
||||
} |
@ -0,0 +1,26 @@ |
||||
import 'package:equatable/equatable.dart'; |
||||
|
||||
enum ServiceStateType { uninitialized, stable, warning } |
||||
enum ServiceTypes { |
||||
messanger, |
||||
mail, |
||||
passwordManager, |
||||
backup, |
||||
github, |
||||
cloud, |
||||
} |
||||
|
||||
class Service extends Equatable { |
||||
const Service({this.state, this.type}); |
||||
|
||||
final ServiceStateType state; |
||||
final ServiceTypes type; |
||||
|
||||
Service updateState(ServiceStateType newState) => Service( |
||||
state: newState, |
||||
type: type, |
||||
); |
||||
|
||||
@override |
||||
List<Object> get props => [state, type]; |
||||
} |
@ -0,0 +1,35 @@ |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:selfprivacy/config/brand_colors.dart'; |
||||
import 'package:selfprivacy/logic/models/service.dart'; |
||||
|
||||
class IconStatusMaks extends StatelessWidget { |
||||
IconStatusMaks({this.child, this.status}); |
||||
final Icon child; |
||||
|
||||
final ServiceStateType status; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
List<Color> colors; |
||||
switch (status) { |
||||
case ServiceStateType.uninitialized: |
||||
colors = BrandColors.uninitializedGradientColors; |
||||
break; |
||||
case ServiceStateType.stable: |
||||
colors = BrandColors.stableGradientColors; |
||||
break; |
||||
case ServiceStateType.warning: |
||||
colors = BrandColors.warningGradientColors; |
||||
break; |
||||
} |
||||
return ShaderMask( |
||||
shaderCallback: (bounds) => LinearGradient( |
||||
begin: Alignment(-1, -0.8), |
||||
end: Alignment(0.9, 0.9), |
||||
colors: colors, |
||||
tileMode: TileMode.mirror, |
||||
).createShader(bounds), |
||||
child: child, |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,110 @@ |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:selfprivacy/config/brand_theme.dart'; |
||||
import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; |
||||
import 'package:selfprivacy/logic/models/service.dart'; |
||||
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; |
||||
import 'package:selfprivacy/ui/components/brand_card/brand_card.dart'; |
||||
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; |
||||
import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart'; |
||||
import 'package:selfprivacy/utils/extensions/text_extension.dart'; |
||||
|
||||
class ServicesPage extends StatefulWidget { |
||||
ServicesPage({Key key}) : super(key: key); |
||||
|
||||
@override |
||||
_ServicesPageState createState() => _ServicesPageState(); |
||||
} |
||||
|
||||
class _ServicesPageState extends State<ServicesPage> { |
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final serviceCubit = context.watch<ServicesCubit>(); |
||||
final connected = serviceCubit.state.connected; |
||||
final uninitialized = serviceCubit.state.uninitialized; |
||||
return Scaffold( |
||||
body: ListView( |
||||
padding: brandPagePadding, |
||||
children: [ |
||||
Text('Сервисы').caption, |
||||
SizedBox(height: 24), |
||||
...connected.map((service) => _Card(service: service)).toList(), |
||||
if (uninitialized.isNotEmpty) ...[ |
||||
Text('не подключены').body1, |
||||
SizedBox(height: 30), |
||||
], |
||||
...uninitialized.map((service) => _Card(service: service)).toList() |
||||
], |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class _Card extends StatelessWidget { |
||||
const _Card({Key key, @required this.service}) : super(key: key); |
||||
|
||||
final Service service; |
||||
@override |
||||
Widget build(BuildContext context) { |
||||
String title; |
||||
IconData iconData; |
||||
String description; |
||||
|
||||
switch (service.type) { |
||||
case ServiceTypes.messanger: |
||||
iconData = BrandIcons.messanger; |
||||
title = 'Мессенджер'; |
||||
description = |
||||
'Delta Chat срфеТекст-текст описание. Если бы мне надо было обсудить что-то от чего зависит жизнь. Я бы выбрал Delta.Chat + свой почтовый сервер.'; |
||||
break; |
||||
case ServiceTypes.mail: |
||||
iconData = BrandIcons.envelope; |
||||
title = 'Почта'; |
||||
description = 'Электронная почта для семьи или компании '; |
||||
break; |
||||
case ServiceTypes.passwordManager: |
||||
iconData = BrandIcons.key; |
||||
title = 'Менеджер паролей'; |
||||
description = 'Надёжное хранилище для ваших паролей и ключей доступа'; |
||||
break; |
||||
case ServiceTypes.github: |
||||
iconData = BrandIcons.github; |
||||
title = 'Git сервер'; |
||||
description = 'Сервис для приватного хранения своих разработок'; |
||||
break; |
||||
case ServiceTypes.backup: |
||||
iconData = BrandIcons.save; |
||||
title = 'Резервное копирование'; |
||||
description = 'Обеспеченье целосности и сохранности ваших данных'; |
||||
break; |
||||
case ServiceTypes.cloud: |
||||
iconData = BrandIcons.upload; |
||||
title = 'Файловое Облако'; |
||||
description = 'Сервис для доступа к вашим файлам в любой точке мира'; |
||||
break; |
||||
} |
||||
return BrandCard( |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
IconStatusMaks( |
||||
status: service.state, |
||||
child: Icon(iconData, size: 30, color: Colors.white), |
||||
), |
||||
SizedBox(height: 10), |
||||
Text(title).h2, |
||||
SizedBox(height: 10), |
||||
if (service.state == ServiceStateType.uninitialized) ...[ |
||||
Text(description).body1, |
||||
SizedBox(height: 10), |
||||
BrandButton.text( |
||||
title: 'Подключить', |
||||
onPressed: () { |
||||
context.read<ServicesCubit>().connect(service); |
||||
}) |
||||
], |
||||
if (service.state == ServiceStateType.stable) Text('Подключен').body1, |
||||
], |
||||
), |
||||
); |
||||
} |
||||
} |
Loading…
Reference in new issue