mirror of
https://github.com/hamaluik/timecop.git
synced 2025-05-20 02:06:30 +08:00
fix FAB once and for all
This commit is contained in:
@ -217,11 +217,12 @@ class MockDataProvider extends DataProvider {
|
||||
Future<void> editProject(Project project) async {}
|
||||
Future<void> deleteProject(Project project) async {}
|
||||
Future<TimerEntry> createTimer({String description, int projectID, DateTime startTime, DateTime endTime}) async {
|
||||
DateTime st = startTime ?? DateTime.now();
|
||||
return TimerEntry(
|
||||
id: -1,
|
||||
description: description,
|
||||
projectID: projectID,
|
||||
startTime: startTime,
|
||||
startTime: st,
|
||||
endTime: endTime,
|
||||
);
|
||||
}
|
||||
|
@ -14,11 +14,10 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_speed_dial_material_design/flutter_speed_dial_material_design.dart';
|
||||
//import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:timecop/blocs/timers/bloc.dart';
|
||||
import 'package:timecop/screens/dashboard/bloc/dashboard_bloc.dart';
|
||||
import 'package:timecop/screens/dashboard/components/StartTimerSpeedDial.dart';
|
||||
|
||||
class StartTimerButton extends StatefulWidget {
|
||||
StartTimerButton({Key key}) : super(key: key);
|
||||
@ -28,14 +27,6 @@ class StartTimerButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _StartTimerButtonState extends State<StartTimerButton> {
|
||||
bool _speedDialOpened;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_speedDialOpened = false;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final DashboardBloc bloc = BlocProvider.of<DashboardBloc>(context);
|
||||
@ -63,114 +54,13 @@ class _StartTimerButtonState extends State<StartTimerButton> {
|
||||
onPressed: () {
|
||||
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
|
||||
assert(timers != null);
|
||||
|
||||
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
|
||||
bloc.add(TimerWasStartedEvent());
|
||||
},
|
||||
);
|
||||
}
|
||||
else {
|
||||
/*return SpeedDial(
|
||||
marginRight: 14,
|
||||
overlayColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
backgroundColor: _speedDialOpened ? Theme.of(context).disabledColor : Theme.of(context).accentColor,
|
||||
foregroundColor: Theme.of(context).accentIconTheme.color,
|
||||
onOpen: () => setState(() => _speedDialOpened = true),
|
||||
onClose: () => setState(() => _speedDialOpened = false),
|
||||
child: Stack(
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 16,
|
||||
child: Icon(FontAwesomeIcons.stopwatch),
|
||||
)
|
||||
],
|
||||
),
|
||||
children: <SpeedDialChild>[
|
||||
SpeedDialChild(
|
||||
child: Icon(FontAwesomeIcons.plus),
|
||||
backgroundColor: Theme.of(context).accentColor,
|
||||
foregroundColor: Theme.of(context).accentIconTheme.color,
|
||||
onTap: () {
|
||||
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
|
||||
assert(timers != null);
|
||||
|
||||
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
|
||||
bloc.add(TimerWasStartedEvent());
|
||||
},
|
||||
),
|
||||
SpeedDialChild(
|
||||
child: Icon(FontAwesomeIcons.stop),
|
||||
backgroundColor: Colors.pink[600],
|
||||
foregroundColor: Theme.of(context).accentIconTheme.color,
|
||||
onTap: () {
|
||||
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
|
||||
assert(timers != null);
|
||||
timers.add(StopAllTimers());
|
||||
},
|
||||
),
|
||||
],
|
||||
);*/
|
||||
return SpeedDialFloatingActionButton(
|
||||
onAction: (int action) {
|
||||
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
|
||||
assert(timers != null);
|
||||
switch(action) {
|
||||
case 0: {
|
||||
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
|
||||
bloc.add(TimerWasStartedEvent());
|
||||
}
|
||||
break;
|
||||
case 1: {
|
||||
timers.add(StopAllTimers());
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
actions: <SpeedDialAction>[
|
||||
SpeedDialAction(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.plus,
|
||||
color: Theme.of(context).accentColor,
|
||||
)
|
||||
),
|
||||
SpeedDialAction(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.stop,
|
||||
color: Colors.pink[600],
|
||||
),
|
||||
)
|
||||
],
|
||||
childOnFold: Stack(
|
||||
key: UniqueKey(),
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 16,
|
||||
child: Icon(FontAwesomeIcons.stopwatch),
|
||||
)
|
||||
],
|
||||
),
|
||||
childOnUnfold: Stack(
|
||||
key: UniqueKey(),
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 16,
|
||||
child: Icon(FontAwesomeIcons.times),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
return StartTimerSpeedDial();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
173
lib/screens/dashboard/components/StartTimerSpeedDial.dart
Normal file
173
lib/screens/dashboard/components/StartTimerSpeedDial.dart
Normal file
@ -0,0 +1,173 @@
|
||||
// Copyright 2020 Kenton Hamaluik
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:timecop/blocs/timers/bloc.dart';
|
||||
import 'package:timecop/screens/dashboard/bloc/dashboard_bloc.dart';
|
||||
|
||||
class StartTimerSpeedDial extends StatefulWidget {
|
||||
StartTimerSpeedDial({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_StartTimerSpeedDialState createState() => _StartTimerSpeedDialState();
|
||||
}
|
||||
|
||||
class _StartTimerSpeedDialState extends State<StartTimerSpeedDial> with TickerProviderStateMixin {
|
||||
AnimationController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 100),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final DashboardBloc bloc = BlocProvider.of<DashboardBloc>(context);
|
||||
assert(bloc != null);
|
||||
|
||||
// adapted from https://stackoverflow.com/a/46480722
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 70.0,
|
||||
width: 56.0,
|
||||
alignment: FractionalOffset.topCenter,
|
||||
child: ScaleTransition(
|
||||
scale: CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: Interval(
|
||||
0.0,
|
||||
1.0,
|
||||
curve: Curves.easeOut
|
||||
),
|
||||
),
|
||||
child: FloatingActionButton(
|
||||
heroTag: null,
|
||||
mini: true,
|
||||
child: Stack(
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 7.5,
|
||||
left: 8,
|
||||
child: Icon(FontAwesomeIcons.plus),
|
||||
)
|
||||
],
|
||||
),
|
||||
backgroundColor: Theme.of(context).accentColor,
|
||||
foregroundColor: Theme.of(context).accentIconTheme.color,
|
||||
onPressed: () {
|
||||
_controller.reverse();
|
||||
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
|
||||
assert(timers != null);
|
||||
timers.add(CreateTimer(description: bloc.state.newDescription, project: bloc.state.newProject));
|
||||
bloc.add(TimerWasStartedEvent());
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 70.0,
|
||||
width: 56.0,
|
||||
alignment: FractionalOffset.topCenter,
|
||||
child: ScaleTransition(
|
||||
scale: CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: Interval(
|
||||
0.0,
|
||||
0.75,
|
||||
curve: Curves.easeOut
|
||||
),
|
||||
),
|
||||
child: FloatingActionButton(
|
||||
heroTag: null,
|
||||
mini: true,
|
||||
child: Stack(
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 7,
|
||||
left: 7.5,
|
||||
child: Icon(FontAwesomeIcons.stop),
|
||||
)
|
||||
],
|
||||
),
|
||||
backgroundColor: Colors.pink[600],
|
||||
foregroundColor: Theme.of(context).accentIconTheme.color,
|
||||
onPressed: () {
|
||||
_controller.reverse();
|
||||
final TimersBloc timers = BlocProvider.of<TimersBloc>(context);
|
||||
assert(timers != null);
|
||||
timers.add(StopAllTimers());
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (BuildContext conext, Widget child) {
|
||||
return
|
||||
FloatingActionButton(
|
||||
heroTag: null,
|
||||
backgroundColor: _controller.isDismissed ? Theme.of(context).accentColor : Theme.of(context).disabledColor,
|
||||
child: _controller.isDismissed
|
||||
? Stack(
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 16,
|
||||
child: Icon(FontAwesomeIcons.stopwatch,),
|
||||
)
|
||||
],
|
||||
)
|
||||
: Stack(
|
||||
// shenanigans to properly centre the icon (font awesome glyphs are variable
|
||||
// width but the library currently doesn't deal with that)
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
Positioned(
|
||||
top: 15,
|
||||
left: 16,
|
||||
child: Icon(FontAwesomeIcons.times),
|
||||
)
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
if (_controller.isDismissed) {
|
||||
_controller.forward();
|
||||
} else {
|
||||
_controller.reverse();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
@ -212,13 +212,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.4"
|
||||
flutter_speed_dial_material_design:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_speed_dial_material_design
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter_svg:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -27,8 +27,6 @@ dependencies:
|
||||
path_provider: ^1.6.1
|
||||
shared_preferences: ^0.5.6+2
|
||||
fluent: ^1.0.1+2
|
||||
#flutter_speed_dial: ^1.2.5
|
||||
flutter_speed_dial_material_design: ^1.1.1
|
||||
fl_chart: ^0.8.3
|
||||
flutter_swiper: ^1.1.6
|
||||
|
||||
|
Reference in New Issue
Block a user