diff --git a/assets/translations/en.json b/assets/translations/en.json index 2000177c4f..cafb848a82 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -189,7 +189,6 @@ "21": "One more restart to apply your security certificates.", "22": "Create master account", "23": "Enter a nickname and strong password" - }, "modals": { "_comment": "messages in modals", @@ -203,5 +202,11 @@ }, "timer": { "sec": "{} sec" + }, + "jobs": { + "_comment": "Jobs list", + "title": "Jobs list", + "start": "Start", + "empty": "No jobs" } } \ No newline at end of file diff --git a/assets/translations/ru.json b/assets/translations/ru.json index 59286277d5..13b9658e41 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -198,9 +198,16 @@ "4": "Сбросить все ключи?", "5": "Да, сбросить", "6": "Удалить сервер и диск?", - "7": "Да, удалить" + "7": "Да, удалить", + "8": "Удалить задачу" }, "timer": { "sec": "{} сек" + }, + "jobs": { + "_comment": "Jobs list", + "title": "Задачи", + "start": "Начать выполенение", + "empty": "Пусто" } } \ No newline at end of file diff --git a/lib/config/bloc_config.dart b/lib/config/bloc_config.dart index af289892f4..ae7b2d81e9 100644 --- a/lib/config/bloc_config.dart +++ b/lib/config/bloc_config.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.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_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/users/users_cubit.dart'; @@ -31,6 +32,7 @@ class BlocAndProviderConfig extends StatelessWidget { ), BlocProvider(create: (_) => ProvidersCubit()), BlocProvider(create: (_) => UsersCubit()), + BlocProvider(create: (_) => JobsCubit()), ], child: child, ); diff --git a/lib/config/brand_shadow.dart b/lib/config/brand_shadow.dart deleted file mode 100644 index 39c97a64bf..0000000000 --- a/lib/config/brand_shadow.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter/material.dart'; - -final shadow8 = BoxShadow( - offset: Offset(0, 4), - blurRadius: 8, - color: Colors.black.withOpacity(.08), -); diff --git a/lib/config/brand_theme.dart b/lib/config/brand_theme.dart index 9f76cc0c78..32b1b45362 100644 --- a/lib/config/brand_theme.dart +++ b/lib/config/brand_theme.dart @@ -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); diff --git a/lib/logic/cubit/jobs/jobs_cubit.dart b/lib/logic/cubit/jobs/jobs_cubit.dart new file mode 100644 index 0000000000..6fa19f6851 --- /dev/null +++ b/lib/logic/cubit/jobs/jobs_cubit.dart @@ -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 { + JobsCubit() : super(JobsState.emtpy()); + + List 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()); + } +} diff --git a/lib/logic/cubit/jobs/jobs_state.dart b/lib/logic/cubit/jobs/jobs_state.dart new file mode 100644 index 0000000000..e761b8170a --- /dev/null +++ b/lib/logic/cubit/jobs/jobs_state.dart @@ -0,0 +1,25 @@ +part of 'jobs_cubit.dart'; + +class JobsState extends Equatable { + const JobsState(this.jobList); + + final List 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 get props => jobList; +} diff --git a/lib/logic/models/job.dart b/lib/logic/models/job.dart new file mode 100644 index 0000000000..e1161daee9 --- /dev/null +++ b/lib/logic/models/job.dart @@ -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 get props => [id, title]; +} diff --git a/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart b/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart new file mode 100644 index 0000000000..3ed4452590 --- /dev/null +++ b/lib/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart @@ -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, + ), + ), + ), + ); + } +} diff --git a/lib/ui/components/brand_button/brand_button.dart b/lib/ui/components/brand_button/brand_button.dart index a2de859262..d3ed28b5a6 100644 --- a/lib/ui/components/brand_button/brand_button.dart +++ b/lib/ui/components/brand_button/brand_button.dart @@ -10,14 +10,14 @@ class BrandButton { static rised({ Key? key, required VoidCallback? onPressed, - String? title, + String? text, Widget? child, }) { - assert(title == 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'); + assert(text != null || child != null, 'required title or child'); return _RisedButton( key: key, - title: title, + title: text, onPressed: onPressed, child: child, ); diff --git a/lib/ui/components/brand_card/brand_card.dart b/lib/ui/components/brand_card/brand_card.dart deleted file mode 100644 index 18fd26eb4c..0000000000 --- a/lib/ui/components/brand_card/brand_card.dart +++ /dev/null @@ -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, - ); - } -} diff --git a/lib/ui/components/brand_cards/brand_cards.dart b/lib/ui/components/brand_cards/brand_cards.dart new file mode 100644 index 0000000000..5d0e7204c3 --- /dev/null +++ b/lib/ui/components/brand_cards/brand_cards.dart @@ -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 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), + ) +]; diff --git a/lib/ui/components/brand_header/brand_header.dart b/lib/ui/components/brand_header/brand_header.dart index fcbac7000a..f9613e088a 100644 --- a/lib/ui/components/brand_header/brand_header.dart +++ b/lib/ui/components/brand_header/brand_header.dart @@ -1,16 +1,19 @@ import 'package:flutter/material.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/pre_styled_buttons/pre_styled_buttons.dart'; class BrandHeader extends StatelessWidget { const BrandHeader({ Key? key, required this.title, this.hasBackButton = false, + this.hasFlashButton = false, }) : super(key: key); final String title; final bool hasBackButton; + final bool hasFlashButton; @override Widget build(BuildContext context) { @@ -31,6 +34,8 @@ class BrandHeader extends StatelessWidget { SizedBox(width: 10), ], BrandText.h4(title), + Spacer(), + if (hasFlashButton) PreStyledButtons.flash(), ], ), ), diff --git a/lib/ui/components/jobs_content/jobs_content.dart b/lib/ui/components/jobs_content/jobs_content.dart new file mode 100644 index 0000000000..c89773ab82 --- /dev/null +++ b/lib/ui/components/jobs_content/jobs_content.dart @@ -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().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().removeJob(j.id), + child: Text('Remove'), + ), + ], + ), + ) + .toList(), + SizedBox(height: 20), + BrandButton.rised( + onPressed: () => context.read().applyAll(), + text: 'jobs.start'.tr(), + ), + ], + ], + ); + } +} diff --git a/lib/ui/components/one_page/one_page.dart b/lib/ui/components/one_page/one_page.dart index 7cb27a83dc..9cb1afe6b7 100644 --- a/lib/ui/components/one_page/one_page.dart +++ b/lib/ui/components/one_page/one_page.dart @@ -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_text/brand_text.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 { const OnePage({ @@ -16,33 +16,31 @@ class OnePage extends StatelessWidget { @override Widget build(BuildContext context) { - return SafeArea( - child: Scaffold( - appBar: PreferredSize( - child: Column( - children: [ - Container( - 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, + return Scaffold( + appBar: PreferredSize( + child: Column( + children: [ + Container( + height: 51, alignment: Alignment.center, - child: PreStyledButtons.close( - onPress: () => Navigator.of(context).pop()), + 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, + child: PreStyledButtons.close( + onPress: () => Navigator.of(context).pop()), ), ), ), diff --git a/lib/ui/components/pre_styled_buttons.dart b/lib/ui/components/pre_styled_buttons/close.dart similarity index 60% rename from lib/ui/components/pre_styled_buttons.dart rename to lib/ui/components/pre_styled_buttons/close.dart index 9a5e8baf57..13f99bcea1 100644 --- a/lib/ui/components/pre_styled_buttons.dart +++ b/lib/ui/components/pre_styled_buttons/close.dart @@ -1,13 +1,4 @@ -import 'package:flutter/material.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); -} +part of 'pre_styled_buttons.dart'; class _CloseButton extends StatelessWidget { const _CloseButton({Key? key, required this.onPress}) : super(key: key); diff --git a/lib/ui/components/pre_styled_buttons/flash.dart b/lib/ui/components/pre_styled_buttons/flash.dart new file mode 100644 index 0000000000..f591c3b11a --- /dev/null +++ b/lib/ui/components/pre_styled_buttons/flash.dart @@ -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().state.isEmpty; + wasPrevStateIsEmpty = hasNoJobs; + var icon = hasNoJobs ? Ionicons.flash_outline : Ionicons.flash; + + return BlocListener( + 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, + ); + }), + ), + ); + } +} diff --git a/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart b/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart new file mode 100644 index 0000000000..f2ce87c95a --- /dev/null +++ b/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart @@ -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(); +} diff --git a/lib/ui/pages/initializing/initializing.dart b/lib/ui/pages/initializing/initializing.dart index f675202c2c..ea0e854413 100644 --- a/lib/ui/pages/initializing/initializing.dart +++ b/lib/ui/pages/initializing/initializing.dart @@ -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/providers/providers_cubit.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_modal_sheet/brand_modal_sheet.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; @@ -50,7 +50,7 @@ class InitializingPage extends StatelessWidget { child: Column( children: [ Padding( - padding: brandPagePadding2.copyWith(top: 10, bottom: 10), + padding: paddingH15V0.copyWith(top: 10, bottom: 10), child: ProgressBar( steps: [ 'Hetzner', @@ -132,7 +132,7 @@ class InitializingPage extends StatelessWidget { onPressed: formCubitState.isSubmitting ? null : () => context.read().trySubmit(), - title: 'basis.connect'.tr(), + text: 'basis.connect'.tr(), ), SizedBox(height: 10), BrandButton.text( @@ -187,7 +187,7 @@ class InitializingPage extends StatelessWidget { onPressed: formCubitState.isSubmitting ? null : () => context.read().trySubmit(), - title: 'basis.connect'.tr(), + text: 'basis.connect'.tr(), ), SizedBox(height: 10), BrandButton.text( @@ -238,7 +238,7 @@ class InitializingPage extends StatelessWidget { onPressed: formCubitState.isSubmitting ? null : () => context.read().trySubmit(), - title: 'basis.connect'.tr(), + text: 'basis.connect'.tr(), ), SizedBox(height: 10), BrandButton.text( @@ -330,7 +330,7 @@ class InitializingPage extends StatelessWidget { SizedBox(height: 30), BrandButton.rised( onPressed: () => context.read().saveDomain(), - title: 'initializing.10'.tr(), + text: 'initializing.10'.tr(), ), ], SizedBox(height: 10), @@ -400,7 +400,7 @@ class InitializingPage extends StatelessWidget { onPressed: formCubitState.isSubmitting ? null : () => context.read().trySubmit(), - title: 'basis.connect'.tr(), + text: 'basis.connect'.tr(), ), SizedBox(height: 10), BrandButton.text( @@ -428,7 +428,7 @@ class InitializingPage extends StatelessWidget { onPressed: isLoading ? null : () => appConfigCubit.createServerAndSetDnsRecords(), - title: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(), + text: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(), ), Spacer(flex: 2), BrandButton.text( @@ -488,8 +488,8 @@ class InitializingPage extends StatelessWidget { Widget _addCard(Widget child) { return Container( height: 450, - padding: brandPagePadding2, - child: BrandCard(child: child), + padding: paddingH15V0, + child: BrandCards.big(child: child), ); } } @@ -503,7 +503,7 @@ class _HowHetzner extends StatelessWidget { Widget build(BuildContext context) { return BrandModalSheet( child: Padding( - padding: brandPagePadding2.copyWith(top: 25), + padding: paddingH15V0.copyWith(top: 25), child: BrandMarkdown( fileName: 'how_hetzner', )), diff --git a/lib/ui/pages/more/app_settings/app_setting.dart b/lib/ui/pages/more/app_settings/app_setting.dart index ce857cab6e..6959b343e9 100644 --- a/lib/ui/pages/more/app_settings/app_setting.dart +++ b/lib/ui/pages/more/app_settings/app_setting.dart @@ -32,7 +32,7 @@ class _AppSettingsPageState extends State { preferredSize: Size.fromHeight(52), ), body: ListView( - padding: brandPagePadding2, + padding: paddingH15V0, children: [ BrandDivider(), Container( diff --git a/lib/ui/pages/more/info/info.dart b/lib/ui/pages/more/info/info.dart index 1ed6aea45a..ef0628a645 100644 --- a/lib/ui/pages/more/info/info.dart +++ b/lib/ui/pages/more/info/info.dart @@ -18,7 +18,7 @@ class InfoPage extends StatelessWidget { preferredSize: Size.fromHeight(52), ), body: ListView( - padding: brandPagePadding2, + padding: paddingH15V0, children: [ BrandDivider(), SizedBox(height: 10), diff --git a/lib/ui/pages/more/more.dart b/lib/ui/pages/more/more.dart index 112b8c64e8..4c1a2d9b6d 100644 --- a/lib/ui/pages/more/more.dart +++ b/lib/ui/pages/more/more.dart @@ -29,7 +29,7 @@ class MorePage extends StatelessWidget { body: ListView( children: [ Padding( - padding: brandPagePadding2, + padding: paddingH15V0, child: Column( children: [ BrandDivider(), diff --git a/lib/ui/pages/onboarding/onboarding.dart b/lib/ui/pages/onboarding/onboarding.dart index 835e40e00f..6416a5b0ff 100644 --- a/lib/ui/pages/onboarding/onboarding.dart +++ b/lib/ui/pages/onboarding/onboarding.dart @@ -79,7 +79,7 @@ class _OnboardingPageState extends State { curve: Curves.easeIn, ); }, - title: 'basis.next'.tr(), + text: 'basis.next'.tr(), ), SizedBox(height: 30), ], @@ -129,7 +129,7 @@ class _OnboardingPageState extends State { (route) => false, ); }, - title: 'basis.got_it'.tr(), + text: 'basis.got_it'.tr(), ), SizedBox(height: 30), ], diff --git a/lib/ui/pages/providers/providers.dart b/lib/ui/pages/providers/providers.dart index 196ab0edf7..44e0bcfd6b 100644 --- a/lib/ui/pages/providers/providers.dart +++ b/lib/ui/pages/providers/providers.dart @@ -1,10 +1,13 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_theme.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/models/job.dart'; import 'package:selfprivacy/logic/models/provider.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_modal_sheet/brand_modal_sheet.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; @@ -46,11 +49,14 @@ class _ProvidersPageState extends State { .toList(); return Scaffold( appBar: PreferredSize( - child: BrandHeader(title: 'providers.page_title'.tr()), + child: BrandHeader( + title: 'providers.page_title'.tr(), + hasFlashButton: true, + ), preferredSize: Size.fromHeight(52), ), body: ListView( - padding: brandPagePadding2, + padding: paddingH15V0, children: [ if (!isReady) ...[ NotReadyCard(), @@ -128,7 +134,7 @@ class _Card extends StatelessWidget { } return GestureDetector( onTap: onTap, - child: BrandCard( + child: BrandCards.big( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -193,6 +199,11 @@ class _ProviderDetails extends StatelessWidget { 'providers.backup.bottom_sheet.2'.tr(args: [domainName, 'Time'])), SizedBox(height: 10), BrandText.body1('providers.backup.status'.tr()), + BrandButton.rised( + onPressed: () => + context.read().addJob(Job(title: 'text')), + text: 'add job', + ) ]; break; } @@ -207,7 +218,7 @@ class _ProviderDetails extends StatelessWidget { children: [ SizedBox(height: 40), Padding( - padding: brandPagePadding2, + padding: paddingH15V0, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/ui/pages/providers/settings/settings.dart b/lib/ui/pages/providers/settings/settings.dart index e2e2294e98..04a71ab190 100644 --- a/lib/ui/pages/providers/settings/settings.dart +++ b/lib/ui/pages/providers/settings/settings.dart @@ -13,7 +13,7 @@ class SettingsPage extends StatelessWidget { @override Widget build(BuildContext context) { return ListView( - padding: brandPagePadding2, + padding: paddingH15V0, children: [ SizedBox(height: 10), BrandHeader(title: 'basis.settings'.tr(), hasBackButton: true), diff --git a/lib/ui/pages/server_details/server_details.dart b/lib/ui/pages/server_details/server_details.dart index 7ae33d70b8..fd1200d7d8 100644 --- a/lib/ui/pages/server_details/server_details.dart +++ b/lib/ui/pages/server_details/server_details.dart @@ -65,7 +65,7 @@ class _ServerDetailsState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: brandPagePadding2, + padding: paddingH15V0, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/ui/pages/server_details/server_settings.dart b/lib/ui/pages/server_details/server_settings.dart index b5d48e08a3..6e2ed6b143 100644 --- a/lib/ui/pages/server_details/server_settings.dart +++ b/lib/ui/pages/server_details/server_settings.dart @@ -11,7 +11,7 @@ class _ServerSettings extends StatelessWidget { @override Widget build(BuildContext context) { return ListView( - padding: brandPagePadding2, + padding: paddingH15V0, children: [ SizedBox(height: 10), Container( diff --git a/lib/ui/pages/services/services.dart b/lib/ui/pages/services/services.dart index d49fe72c43..d0fee3257a 100644 --- a/lib/ui/pages/services/services.dart +++ b/lib/ui/pages/services/services.dart @@ -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/models/state_types.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_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; @@ -31,11 +31,14 @@ class _ServicesPageState extends State { return Scaffold( appBar: PreferredSize( - child: BrandHeader(title: 'basis.services'.tr()), + child: BrandHeader( + title: 'basis.services'.tr(), + hasFlashButton: true, + ), preferredSize: Size.fromHeight(52), ), body: ListView( - padding: brandPagePadding2, + padding: paddingH15V0, children: [ BrandText.body1('services.title'.tr()), SizedBox(height: 24), @@ -119,7 +122,7 @@ class _Card extends StatelessWidget { ); }, ), - child: BrandCard( + child: BrandCards.big( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -359,7 +362,7 @@ class _ServiceDetails extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: brandPagePadding1, + padding: paddingH15V30, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -376,7 +379,7 @@ class _ServiceDetails extends StatelessWidget { child: Container( child: BrandButton.rised( onPressed: () => Navigator.of(context).pop(), - title: 'basis.close'.tr(), + text: 'basis.close'.tr(), ), ), ), diff --git a/lib/ui/pages/users/new_user.dart b/lib/ui/pages/users/new_user.dart index 62eb624f6f..04792623d1 100644 --- a/lib/ui/pages/users/new_user.dart +++ b/lib/ui/pages/users/new_user.dart @@ -28,7 +28,7 @@ class _NewUser extends StatelessWidget { ), SizedBox(width: 14), Padding( - padding: brandPagePadding2, + padding: paddingH15V0, child: Column( children: [ CubitFormTextField( @@ -62,7 +62,7 @@ class _NewUser extends StatelessWidget { onPressed: formCubitState.isSubmitting ? null : () => context.read().trySubmit(), - title: 'basis.create'.tr(), + text: 'basis.create'.tr(), ), SizedBox(height: 40), Text('users.new_user_info_note'.tr()), diff --git a/lib/ui/pages/users/user.dart b/lib/ui/pages/users/user.dart index f01a362afa..dc7249483b 100644 --- a/lib/ui/pages/users/user.dart +++ b/lib/ui/pages/users/user.dart @@ -18,7 +18,7 @@ class _User extends StatelessWidget { ); }, child: Container( - padding: brandPagePadding2, + padding: paddingH15V0, height: 48, child: Row( children: [ diff --git a/lib/ui/pages/users/user_details.dart b/lib/ui/pages/users/user_details.dart index 3c788bec14..517c98ab4f 100644 --- a/lib/ui/pages/users/user_details.dart +++ b/lib/ui/pages/users/user_details.dart @@ -123,7 +123,7 @@ class _UserDetails extends StatelessWidget { ), SizedBox(height: 20), Padding( - padding: brandPagePadding2.copyWith(bottom: 20), + padding: paddingH15V0.copyWith(bottom: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/ui/pages/users/users.dart b/lib/ui/pages/users/users.dart index 271182e6c8..6200e5d9b2 100644 --- a/lib/ui/pages/users/users.dart +++ b/lib/ui/pages/users/users.dart @@ -53,7 +53,10 @@ class UsersPage extends StatelessWidget { return Scaffold( appBar: PreferredSize( - child: BrandHeader(title: 'basis.users'.tr()), + child: BrandHeader( + title: 'basis.users'.tr(), + hasFlashButton: true, + ), preferredSize: Size.fromHeight(52), ), floatingActionButton: isReady ? _Fab() : null, diff --git a/lib/utils/extensions/elevation_extension.dart b/lib/utils/extensions/elevation_extension.dart index 8be106fa7e..d39be2ac63 100644 --- a/lib/utils/extensions/elevation_extension.dart +++ b/lib/utils/extensions/elevation_extension.dart @@ -2,10 +2,8 @@ library elevation_extension; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; -import 'package:selfprivacy/config/brand_shadow.dart'; extension ElevationExtension on BoxDecoration { - BoxDecoration get ev8 => copyWith(boxShadow: [shadow8]); BoxDecoration copyWith({ Color? color, diff --git a/pubspec.lock b/pubspec.lock index 6e9b275774..d35a69f0ad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -184,7 +184,7 @@ packages: source: hosted version: "4.0.1" crypto: - dependency: "direct main" + dependency: transitive description: name: crypto url: "https://pub.dartlang.org" @@ -420,6 +420,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + ionicons: + dependency: "direct main" + description: + name: ionicons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" js: dependency: transitive description: @@ -483,6 +490,20 @@ packages: url: "https://pub.dartlang.org" source: hosted 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: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 83e61f3bfa..a3ced3fe2e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,6 @@ dependencies: flutter: sdk: flutter crypt: ^4.0.1 - crypto: ^3.0.0 cubit_form: ^1.0.0-nullsafety.0 cupertino_icons: ^1.0.2 dio: ^4.0.0-beta7 @@ -25,7 +24,10 @@ dependencies: get_it: ^6.0.0 hive: ^2.0.0 hive_flutter: ^1.0.0 + ionicons: ^0.1.2 json_annotation: ^4.0.0 + modal_bottom_sheet: ^2.0.0 + nanoid: ^1.0.0 package_info: ^2.0.0 pretty_dio_logger: ^1.1.1 provider: ^5.0.0