master
Kherel 2021-05-25 23:53:54 +02:00
parent e849b551fc
commit d3f494adeb
35 changed files with 442 additions and 119 deletions

View File

@ -189,7 +189,6 @@
"21": "One more restart to apply your security certificates.", "21": "One more restart to apply your security certificates.",
"22": "Create master account", "22": "Create master account",
"23": "Enter a nickname and strong password" "23": "Enter a nickname and strong password"
}, },
"modals": { "modals": {
"_comment": "messages in modals", "_comment": "messages in modals",
@ -203,5 +202,11 @@
}, },
"timer": { "timer": {
"sec": "{} sec" "sec": "{} sec"
},
"jobs": {
"_comment": "Jobs list",
"title": "Jobs list",
"start": "Start",
"empty": "No jobs"
} }
} }

View File

@ -198,9 +198,16 @@
"4": "Сбросить все ключи?", "4": "Сбросить все ключи?",
"5": "Да, сбросить", "5": "Да, сбросить",
"6": "Удалить сервер и диск?", "6": "Удалить сервер и диск?",
"7": "Да, удалить" "7": "Да, удалить",
"8": "Удалить задачу"
}, },
"timer": { "timer": {
"sec": "{} сек" "sec": "{} сек"
},
"jobs": {
"_comment": "Jobs list",
"title": "Задачи",
"start": "Начать выполенение",
"empty": "Пусто"
} }
} }

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
@ -31,6 +32,7 @@ class BlocAndProviderConfig extends StatelessWidget {
), ),
BlocProvider(create: (_) => ProvidersCubit()), BlocProvider(create: (_) => ProvidersCubit()),
BlocProvider(create: (_) => UsersCubit()), BlocProvider(create: (_) => UsersCubit()),
BlocProvider(create: (_) => JobsCubit()),
], ],
child: child, child: child,
); );

View File

@ -1,7 +0,0 @@
import 'package:flutter/material.dart';
final shadow8 = BoxShadow(
offset: Offset(0, 4),
blurRadius: 8,
color: Colors.black.withOpacity(.08),
);

View File

@ -76,6 +76,6 @@ var darkTheme = ligtTheme.copyWith(
), ),
); );
final brandPagePadding1 = EdgeInsets.symmetric(horizontal: 15, vertical: 30); final paddingH15V30 = EdgeInsets.symmetric(horizontal: 15, vertical: 30);
final brandPagePadding2 = EdgeInsets.symmetric(horizontal: 15); final paddingH15V0 = EdgeInsets.symmetric(horizontal: 15);

View File

@ -0,0 +1,27 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/logic/models/job.dart';
import 'package:equatable/equatable.dart';
export 'package:provider/provider.dart';
part 'jobs_state.dart';
class JobsCubit extends Cubit<JobsState> {
JobsCubit() : super(JobsState.emtpy());
List<Job> jobsList = [];
void addJob(Job job) {
final newState = state.addJob(job);
emit(newState);
}
void removeJob(String id) {
final newState = state.removeById(id);
emit(newState);
}
void applyAll() {
print(state.jobList);
emit(JobsState.emtpy());
}
}

View File

@ -0,0 +1,25 @@
part of 'jobs_cubit.dart';
class JobsState extends Equatable {
const JobsState(this.jobList);
final List<Job> jobList;
static JobsState emtpy() => JobsState([]);
bool get isEmpty => jobList.isEmpty;
JobsState addJob(Job job) {
var newJobsList = [...jobList];
newJobsList.add(job);
return JobsState(newJobsList);
}
JobsState removeById(String id) {
var newJobsList = jobList.where((element) => element.id != id).toList();
return JobsState(newJobsList);
}
@override
List<Object> get props => jobList;
}

15
lib/logic/models/job.dart Normal file
View File

@ -0,0 +1,15 @@
import 'package:equatable/equatable.dart';
import 'package:selfprivacy/utils/password_generator2.dart';
class Job extends Equatable {
Job({
String? id,
required this.title,
}) : id = id ?? getRandomString(5);
final String title;
final String id;
@override
List<Object> get props => [id, title];
}

View File

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_theme.dart';
class BrandBottomSheet extends StatelessWidget {
const BrandBottomSheet({Key? key, required this.child}) : super(key: key);
final Widget child;
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
60,
child: Scaffold(
body: SingleChildScrollView(
physics: ClampingScrollPhysics(),
child: Container(
padding: paddingH15V0,
child: child,
),
),
),
);
}
}

View File

@ -10,14 +10,14 @@ class BrandButton {
static rised({ static rised({
Key? key, Key? key,
required VoidCallback? onPressed, required VoidCallback? onPressed,
String? title, String? text,
Widget? child, Widget? child,
}) { }) {
assert(title == null || child == null, 'required title or child'); assert(text == null || child == null, 'required title or child');
assert(title != null || child != null, 'required title or child'); assert(text != null || child != null, 'required title or child');
return _RisedButton( return _RisedButton(
key: key, key: key,
title: title, title: text,
onPressed: onPressed, onPressed: onPressed,
child: child, child: child,
); );

View File

@ -1,29 +0,0 @@
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/utils/extensions/elevation_extension.dart';
class BrandCard extends StatelessWidget {
const BrandCard({
Key? key,
this.child,
}) : super(key: key);
final Widget? child;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? BrandColors.black
: BrandColors.white,
borderRadius: BorderRadius.circular(20),
).ev8,
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 15,
),
child: child,
);
}
}

View File

@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_colors.dart';
class BrandCards {
static Widget big({required Widget child}) => _BrandCard(
child: child,
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 15,
),
shadow: bigShadow,
borderRadius: BorderRadius.circular(20),
);
static Widget small({required Widget child}) => _BrandCard(
child: child,
padding: EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
shadow: bigShadow,
borderRadius: BorderRadius.circular(10),
);
}
class _BrandCard extends StatelessWidget {
const _BrandCard({
Key? key,
required this.child,
required this.padding,
required this.shadow,
required this.borderRadius,
}) : super(key: key);
final Widget child;
final EdgeInsets padding;
final List<BoxShadow> shadow;
final BorderRadius borderRadius;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? BrandColors.black
: BrandColors.white,
borderRadius: borderRadius,
boxShadow: shadow,
),
padding: padding,
child: child,
);
}
}
final bigShadow = [
BoxShadow(
offset: Offset(0, 4),
blurRadius: 8,
color: Colors.black.withOpacity(.08),
)
];

View File

@ -1,16 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:selfprivacy/ui/components/pre_styled_buttons/pre_styled_buttons.dart';
class BrandHeader extends StatelessWidget { class BrandHeader extends StatelessWidget {
const BrandHeader({ const BrandHeader({
Key? key, Key? key,
required this.title, required this.title,
this.hasBackButton = false, this.hasBackButton = false,
this.hasFlashButton = false,
}) : super(key: key); }) : super(key: key);
final String title; final String title;
final bool hasBackButton; final bool hasBackButton;
final bool hasFlashButton;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -31,6 +34,8 @@ class BrandHeader extends StatelessWidget {
SizedBox(width: 10), SizedBox(width: 10),
], ],
BrandText.h4(title), BrandText.h4(title),
Spacer(),
if (hasFlashButton) PreStyledButtons.flash(),
], ],
), ),
), ),

View File

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
import 'package:selfprivacy/ui/components/brand_cards/brand_cards.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
class JobsContent extends StatelessWidget {
const JobsContent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var jobs = context.watch<JobsCubit>().state;
return Column(
children: [
SizedBox(height: 15),
Center(
child: BrandText.h2(
'jobs.title'.tr(),
),
),
if (jobs.isEmpty)
Padding(
padding: const EdgeInsets.only(top: 50),
child: BrandText.body1('jobs.empty'.tr()),
),
if (!jobs.isEmpty) ...[
...jobs.jobList
.map(
(j) => Row(
children: [
Expanded(
child: BrandCards.small(
child: Row(
children: [
BrandText.body1(j.title),
],
),
),
),
SizedBox(width: 10),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: BrandColors.red1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
onPressed: () =>
context.read<JobsCubit>().removeJob(j.id),
child: Text('Remove'),
),
],
),
)
.toList(),
SizedBox(height: 20),
BrandButton.rised(
onPressed: () => context.read<JobsCubit>().applyAll(),
text: 'jobs.start'.tr(),
),
],
],
);
}
}

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart'; import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/ui/components/pre_styled_buttons.dart'; import 'package:selfprivacy/ui/components/pre_styled_buttons/pre_styled_buttons.dart';
class OnePage extends StatelessWidget { class OnePage extends StatelessWidget {
const OnePage({ const OnePage({
@ -16,33 +16,31 @@ class OnePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SafeArea( return Scaffold(
child: Scaffold( appBar: PreferredSize(
appBar: PreferredSize( child: Column(
child: Column( children: [
children: [ Container(
Container( height: 51,
height: 51,
alignment: Alignment.center,
padding: EdgeInsets.symmetric(horizontal: 15),
child: BrandText.h4('basis.details'.tr()),
),
BrandDivider(),
],
),
preferredSize: Size.fromHeight(52),
),
body: child,
bottomNavigationBar: SafeArea(
child: Container(
decoration: BoxDecoration(boxShadow: kElevationToShadow[3]),
height: kBottomNavigationBarHeight,
child: Container(
color: Theme.of(context).scaffoldBackgroundColor,
alignment: Alignment.center, alignment: Alignment.center,
child: PreStyledButtons.close( padding: EdgeInsets.symmetric(horizontal: 15),
onPress: () => Navigator.of(context).pop()), child: BrandText.h4('basis.details'.tr()),
), ),
BrandDivider(),
],
),
preferredSize: Size.fromHeight(52),
),
body: child,
bottomNavigationBar: SafeArea(
child: Container(
decoration: BoxDecoration(boxShadow: kElevationToShadow[3]),
height: kBottomNavigationBarHeight,
child: Container(
color: Theme.of(context).scaffoldBackgroundColor,
alignment: Alignment.center,
child: PreStyledButtons.close(
onPress: () => Navigator.of(context).pop()),
), ),
), ),
), ),

View File

@ -1,13 +1,4 @@
import 'package:flutter/material.dart'; part of 'pre_styled_buttons.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:easy_localization/easy_localization.dart';
class PreStyledButtons {
static Widget close({
required VoidCallback onPress,
}) =>
_CloseButton(onPress: onPress);
}
class _CloseButton extends StatelessWidget { class _CloseButton extends StatelessWidget {
const _CloseButton({Key? key, required this.onPress}) : super(key: key); const _CloseButton({Key? key, required this.onPress}) : super(key: key);

View File

@ -0,0 +1,70 @@
part of 'pre_styled_buttons.dart';
class _BrandFlashButton extends StatefulWidget {
_BrandFlashButton({Key? key}) : super(key: key);
@override
_BrandFlashButtonState createState() => _BrandFlashButtonState();
}
class _BrandFlashButtonState extends State<_BrandFlashButton>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation _colorTween;
@override
void initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 600));
_colorTween = ColorTween(
begin: BrandColors.black,
end: BrandColors.primary,
).animate(_animationController);
super.initState();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
late bool wasPrevStateIsEmpty;
@override
Widget build(BuildContext context) {
var hasNoJobs = context.watch<JobsCubit>().state.isEmpty;
wasPrevStateIsEmpty = hasNoJobs;
var icon = hasNoJobs ? Ionicons.flash_outline : Ionicons.flash;
return BlocListener<JobsCubit, JobsState>(
listener: (context, state) {
if (wasPrevStateIsEmpty && state.jobList.isNotEmpty) {
wasPrevStateIsEmpty = false;
_animationController.forward();
} else if (!wasPrevStateIsEmpty && state.jobList.isEmpty) {
_animationController.reverse();
}
},
child: IconButton(
onPressed: () {
showCupertinoModalBottomSheet(
expand: false,
context: context,
builder: (context) => BrandBottomSheet(
child: JobsContent(),
),
);
},
icon: AnimatedBuilder(
animation: _colorTween,
builder: (context, child) {
return Icon(
icon,
color: _colorTween.value,
);
}),
),
);
}
}

View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:ionicons/ionicons.dart';
import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart';
part 'close.dart';
part 'flash.dart';
class PreStyledButtons {
static Widget close({
required VoidCallback onPress,
}) =>
_CloseButton(onPress: onPress);
static Widget flash() => _BrandFlashButton();
}

View File

@ -11,7 +11,7 @@ import 'package:selfprivacy/logic/cubit/forms/initializing/root_user_form_cubit.
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.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_cards/brand_cards.dart';
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart'; import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart'; import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
@ -50,7 +50,7 @@ class InitializingPage extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
Padding( Padding(
padding: brandPagePadding2.copyWith(top: 10, bottom: 10), padding: paddingH15V0.copyWith(top: 10, bottom: 10),
child: ProgressBar( child: ProgressBar(
steps: [ steps: [
'Hetzner', 'Hetzner',
@ -132,7 +132,7 @@ class InitializingPage extends StatelessWidget {
onPressed: formCubitState.isSubmitting onPressed: formCubitState.isSubmitting
? null ? null
: () => context.read<HetznerFormCubit>().trySubmit(), : () => context.read<HetznerFormCubit>().trySubmit(),
title: 'basis.connect'.tr(), text: 'basis.connect'.tr(),
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
@ -187,7 +187,7 @@ class InitializingPage extends StatelessWidget {
onPressed: formCubitState.isSubmitting onPressed: formCubitState.isSubmitting
? null ? null
: () => context.read<CloudFlareFormCubit>().trySubmit(), : () => context.read<CloudFlareFormCubit>().trySubmit(),
title: 'basis.connect'.tr(), text: 'basis.connect'.tr(),
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
@ -238,7 +238,7 @@ class InitializingPage extends StatelessWidget {
onPressed: formCubitState.isSubmitting onPressed: formCubitState.isSubmitting
? null ? null
: () => context.read<BackblazeFormCubit>().trySubmit(), : () => context.read<BackblazeFormCubit>().trySubmit(),
title: 'basis.connect'.tr(), text: 'basis.connect'.tr(),
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
@ -330,7 +330,7 @@ class InitializingPage extends StatelessWidget {
SizedBox(height: 30), SizedBox(height: 30),
BrandButton.rised( BrandButton.rised(
onPressed: () => context.read<DomainSetupCubit>().saveDomain(), onPressed: () => context.read<DomainSetupCubit>().saveDomain(),
title: 'initializing.10'.tr(), text: 'initializing.10'.tr(),
), ),
], ],
SizedBox(height: 10), SizedBox(height: 10),
@ -400,7 +400,7 @@ class InitializingPage extends StatelessWidget {
onPressed: formCubitState.isSubmitting onPressed: formCubitState.isSubmitting
? null ? null
: () => context.read<RootUserFormCubit>().trySubmit(), : () => context.read<RootUserFormCubit>().trySubmit(),
title: 'basis.connect'.tr(), text: 'basis.connect'.tr(),
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
@ -428,7 +428,7 @@ class InitializingPage extends StatelessWidget {
onPressed: isLoading onPressed: isLoading
? null ? null
: () => appConfigCubit.createServerAndSetDnsRecords(), : () => appConfigCubit.createServerAndSetDnsRecords(),
title: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(), text: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(),
), ),
Spacer(flex: 2), Spacer(flex: 2),
BrandButton.text( BrandButton.text(
@ -488,8 +488,8 @@ class InitializingPage extends StatelessWidget {
Widget _addCard(Widget child) { Widget _addCard(Widget child) {
return Container( return Container(
height: 450, height: 450,
padding: brandPagePadding2, padding: paddingH15V0,
child: BrandCard(child: child), child: BrandCards.big(child: child),
); );
} }
} }
@ -503,7 +503,7 @@ class _HowHetzner extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BrandModalSheet( return BrandModalSheet(
child: Padding( child: Padding(
padding: brandPagePadding2.copyWith(top: 25), padding: paddingH15V0.copyWith(top: 25),
child: BrandMarkdown( child: BrandMarkdown(
fileName: 'how_hetzner', fileName: 'how_hetzner',
)), )),

View File

@ -32,7 +32,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
preferredSize: Size.fromHeight(52), preferredSize: Size.fromHeight(52),
), ),
body: ListView( body: ListView(
padding: brandPagePadding2, padding: paddingH15V0,
children: [ children: [
BrandDivider(), BrandDivider(),
Container( Container(

View File

@ -18,7 +18,7 @@ class InfoPage extends StatelessWidget {
preferredSize: Size.fromHeight(52), preferredSize: Size.fromHeight(52),
), ),
body: ListView( body: ListView(
padding: brandPagePadding2, padding: paddingH15V0,
children: [ children: [
BrandDivider(), BrandDivider(),
SizedBox(height: 10), SizedBox(height: 10),

View File

@ -29,7 +29,7 @@ class MorePage extends StatelessWidget {
body: ListView( body: ListView(
children: [ children: [
Padding( Padding(
padding: brandPagePadding2, padding: paddingH15V0,
child: Column( child: Column(
children: [ children: [
BrandDivider(), BrandDivider(),

View File

@ -79,7 +79,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
curve: Curves.easeIn, curve: Curves.easeIn,
); );
}, },
title: 'basis.next'.tr(), text: 'basis.next'.tr(),
), ),
SizedBox(height: 30), SizedBox(height: 30),
], ],
@ -129,7 +129,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
(route) => false, (route) => false,
); );
}, },
title: 'basis.got_it'.tr(), text: 'basis.got_it'.tr(),
), ),
SizedBox(height: 30), SizedBox(height: 30),
], ],

View File

@ -1,10 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
import 'package:selfprivacy/logic/models/job.dart';
import 'package:selfprivacy/logic/models/provider.dart'; import 'package:selfprivacy/logic/models/provider.dart';
import 'package:selfprivacy/logic/models/state_types.dart'; import 'package:selfprivacy/logic/models/state_types.dart';
import 'package:selfprivacy/ui/components/brand_card/brand_card.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
import 'package:selfprivacy/ui/components/brand_cards/brand_cards.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart'; import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
@ -46,11 +49,14 @@ class _ProvidersPageState extends State<ProvidersPage> {
.toList(); .toList();
return Scaffold( return Scaffold(
appBar: PreferredSize( appBar: PreferredSize(
child: BrandHeader(title: 'providers.page_title'.tr()), child: BrandHeader(
title: 'providers.page_title'.tr(),
hasFlashButton: true,
),
preferredSize: Size.fromHeight(52), preferredSize: Size.fromHeight(52),
), ),
body: ListView( body: ListView(
padding: brandPagePadding2, padding: paddingH15V0,
children: [ children: [
if (!isReady) ...[ if (!isReady) ...[
NotReadyCard(), NotReadyCard(),
@ -128,7 +134,7 @@ class _Card extends StatelessWidget {
} }
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,
child: BrandCard( child: BrandCards.big(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -193,6 +199,11 @@ class _ProviderDetails extends StatelessWidget {
'providers.backup.bottom_sheet.2'.tr(args: [domainName, 'Time'])), 'providers.backup.bottom_sheet.2'.tr(args: [domainName, 'Time'])),
SizedBox(height: 10), SizedBox(height: 10),
BrandText.body1('providers.backup.status'.tr()), BrandText.body1('providers.backup.status'.tr()),
BrandButton.rised(
onPressed: () =>
context.read<JobsCubit>().addJob(Job(title: 'text')),
text: 'add job',
)
]; ];
break; break;
} }
@ -207,7 +218,7 @@ class _ProviderDetails extends StatelessWidget {
children: [ children: [
SizedBox(height: 40), SizedBox(height: 40),
Padding( Padding(
padding: brandPagePadding2, padding: paddingH15V0,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View File

@ -13,7 +13,7 @@ class SettingsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView( return ListView(
padding: brandPagePadding2, padding: paddingH15V0,
children: [ children: [
SizedBox(height: 10), SizedBox(height: 10),
BrandHeader(title: 'basis.settings'.tr(), hasBackButton: true), BrandHeader(title: 'basis.settings'.tr(), hasBackButton: true),

View File

@ -65,7 +65,7 @@ class _ServerDetailsState extends State<ServerDetails>
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: brandPagePadding2, padding: paddingH15V0,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View File

@ -11,7 +11,7 @@ class _ServerSettings extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView( return ListView(
padding: brandPagePadding2, padding: paddingH15V0,
children: [ children: [
SizedBox(height: 10), SizedBox(height: 10),
Container( Container(

View File

@ -5,7 +5,7 @@ import 'package:selfprivacy/config/text_themes.dart';
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
import 'package:selfprivacy/logic/models/state_types.dart'; import 'package:selfprivacy/logic/models/state_types.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.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_cards/brand_cards.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
@ -31,11 +31,14 @@ class _ServicesPageState extends State<ServicesPage> {
return Scaffold( return Scaffold(
appBar: PreferredSize( appBar: PreferredSize(
child: BrandHeader(title: 'basis.services'.tr()), child: BrandHeader(
title: 'basis.services'.tr(),
hasFlashButton: true,
),
preferredSize: Size.fromHeight(52), preferredSize: Size.fromHeight(52),
), ),
body: ListView( body: ListView(
padding: brandPagePadding2, padding: paddingH15V0,
children: [ children: [
BrandText.body1('services.title'.tr()), BrandText.body1('services.title'.tr()),
SizedBox(height: 24), SizedBox(height: 24),
@ -119,7 +122,7 @@ class _Card extends StatelessWidget {
); );
}, },
), ),
child: BrandCard( child: BrandCards.big(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -359,7 +362,7 @@ class _ServiceDetails extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: brandPagePadding1, padding: paddingH15V30,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -376,7 +379,7 @@ class _ServiceDetails extends StatelessWidget {
child: Container( child: Container(
child: BrandButton.rised( child: BrandButton.rised(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
title: 'basis.close'.tr(), text: 'basis.close'.tr(),
), ),
), ),
), ),

View File

@ -28,7 +28,7 @@ class _NewUser extends StatelessWidget {
), ),
SizedBox(width: 14), SizedBox(width: 14),
Padding( Padding(
padding: brandPagePadding2, padding: paddingH15V0,
child: Column( child: Column(
children: [ children: [
CubitFormTextField( CubitFormTextField(
@ -62,7 +62,7 @@ class _NewUser extends StatelessWidget {
onPressed: formCubitState.isSubmitting onPressed: formCubitState.isSubmitting
? null ? null
: () => context.read<UserFormCubit>().trySubmit(), : () => context.read<UserFormCubit>().trySubmit(),
title: 'basis.create'.tr(), text: 'basis.create'.tr(),
), ),
SizedBox(height: 40), SizedBox(height: 40),
Text('users.new_user_info_note'.tr()), Text('users.new_user_info_note'.tr()),

View File

@ -18,7 +18,7 @@ class _User extends StatelessWidget {
); );
}, },
child: Container( child: Container(
padding: brandPagePadding2, padding: paddingH15V0,
height: 48, height: 48,
child: Row( child: Row(
children: [ children: [

View File

@ -123,7 +123,7 @@ class _UserDetails extends StatelessWidget {
), ),
SizedBox(height: 20), SizedBox(height: 20),
Padding( Padding(
padding: brandPagePadding2.copyWith(bottom: 20), padding: paddingH15V0.copyWith(bottom: 20),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

View File

@ -53,7 +53,10 @@ class UsersPage extends StatelessWidget {
return Scaffold( return Scaffold(
appBar: PreferredSize( appBar: PreferredSize(
child: BrandHeader(title: 'basis.users'.tr()), child: BrandHeader(
title: 'basis.users'.tr(),
hasFlashButton: true,
),
preferredSize: Size.fromHeight(52), preferredSize: Size.fromHeight(52),
), ),
floatingActionButton: isReady ? _Fab() : null, floatingActionButton: isReady ? _Fab() : null,

View File

@ -2,10 +2,8 @@ library elevation_extension;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:selfprivacy/config/brand_shadow.dart';
extension ElevationExtension on BoxDecoration { extension ElevationExtension on BoxDecoration {
BoxDecoration get ev8 => copyWith(boxShadow: [shadow8]);
BoxDecoration copyWith({ BoxDecoration copyWith({
Color? color, Color? color,

View File

@ -184,7 +184,7 @@ packages:
source: hosted source: hosted
version: "4.0.1" version: "4.0.1"
crypto: crypto:
dependency: "direct main" dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
@ -420,6 +420,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
ionicons:
dependency: "direct main"
description:
name: ionicons
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
js: js:
dependency: transitive dependency: transitive
description: description:
@ -483,6 +490,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
modal_bottom_sheet:
dependency: "direct main"
description:
name: modal_bottom_sheet
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
nanoid:
dependency: "direct main"
description:
name: nanoid
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:

View File

@ -11,7 +11,6 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
crypt: ^4.0.1 crypt: ^4.0.1
crypto: ^3.0.0
cubit_form: ^1.0.0-nullsafety.0 cubit_form: ^1.0.0-nullsafety.0
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
dio: ^4.0.0-beta7 dio: ^4.0.0-beta7
@ -25,7 +24,10 @@ dependencies:
get_it: ^6.0.0 get_it: ^6.0.0
hive: ^2.0.0 hive: ^2.0.0
hive_flutter: ^1.0.0 hive_flutter: ^1.0.0
ionicons: ^0.1.2
json_annotation: ^4.0.0 json_annotation: ^4.0.0
modal_bottom_sheet: ^2.0.0
nanoid: ^1.0.0
package_info: ^2.0.0 package_info: ^2.0.0
pretty_dio_logger: ^1.1.1 pretty_dio_logger: ^1.1.1
provider: ^5.0.0 provider: ^5.0.0