Skip to content

Commit

Permalink
Merge pull request #115 from icapps/feature/nested-touch-feedback-and…
Browse files Browse the repository at this point in the history
…roid

Feature/nested touch feedback android
  • Loading branch information
ikbendewilliam authored Feb 13, 2024
2 parents 7017aa2 + a1028b8 commit 7358ce9
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 149 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# Changelog
## [2.1.5] - 2024-02-12
### Changed
- Fixed missing material in the TouchFeedback widget
- Updated dependencies (logger to v2, connectivity_plus to v5)

## [2.1.4+2] - 2024-02-09
## [2.1.4+1] - 2024-02-09
### Changed
- Issue where android clips outside of the TouchFeedback widget (breaking shadows etc)

## [2.1.4] - 2024-02-09
### Added
- Improved TouchFeedBack android implementation by using a custom inkwell that draws on top of its child and can be nested. See the example for more information.
Expand Down
2 changes: 1 addition & 1 deletion example/lib/viewmodel/logger_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class LoggerViewModel with ChangeNotifierEx {
LoggingConfiguration(
isEnabled: true,
shouldLogNetworkInfo: true,
loggingLevel: Level.verbose,
loggingLevel: Level.trace,
onLog: _onLog,
),
);
Expand Down
12 changes: 6 additions & 6 deletions lib/src/util/logging/impl/LoggerPrinter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ import 'package:logger/logger.dart';
@immutable
class OurPrettyPrinter extends LogPrinter {
static final levelColors = {
Level.verbose: AnsiColor.fg(AnsiColor.grey(0.5)),
Level.trace: AnsiColor.fg(AnsiColor.grey(0.5)),
Level.debug: AnsiColor.none(),
Level.info: AnsiColor.fg(12),
Level.warning: AnsiColor.fg(208),
Level.error: AnsiColor.fg(196),
Level.wtf: AnsiColor.fg(199),
Level.fatal: AnsiColor.fg(199),
};

static final levelEmojis = {
Level.verbose: '',
Level.trace: '',
Level.debug: '🐛 ',
Level.info: '💡 ',
Level.warning: '⚠️ ',
Level.error: '⛔ ',
Level.wtf: '👾 ',
Level.fatal: '👾 ',
};

/// Matches a stacktrace line as generated on Android/iOS devices.
Expand Down Expand Up @@ -145,8 +145,8 @@ class OurPrettyPrinter extends LogPrinter {

AnsiColor _getErrorColor(Level level) {
if (colors) {
if (level == Level.wtf) {
return levelColors[Level.wtf]!.toBg();
if (level == Level.fatal) {
return levelColors[Level.fatal]!.toBg();
} else {
return levelColors[Level.error]!.toBg();
}
Expand Down
93 changes: 47 additions & 46 deletions lib/src/util/logging/logging.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,35 @@ class LoggingConfiguration {
this.printTime = true,
this.onLog,
this.isEnabled = true,
this.loggingLevel = Level.verbose,
this.loggingLevel = Level.trace,
});
}

abstract class Log {
void verbose(String message, {dynamic error, StackTrace? trace});
void trace(String message, {dynamic error, StackTrace? stackTrace});

void debug(String message, {dynamic error, StackTrace? trace});
void debug(String message, {dynamic error, StackTrace? stackTrace});

void info(String message, {dynamic error, StackTrace? trace});
void info(String message, {dynamic error, StackTrace? stackTrace});

void warning(String message, {dynamic error, StackTrace? trace});
void warning(String message, {dynamic error, StackTrace? stackTrace});

void error(String message, {dynamic error, StackTrace? trace});
void error(String message, {dynamic error, StackTrace? stackTrace});

void v(String message, {dynamic error, StackTrace? trace}) =>
verbose(message, error: error, trace: trace);
void t(String message, {dynamic error, StackTrace? stackTrace}) =>
trace(message, error: error, stackTrace: stackTrace);

void d(String message, {dynamic error, StackTrace? trace}) =>
debug(message, error: error, trace: trace);
void d(String message, {dynamic error, StackTrace? stackTrace}) =>
debug(message, error: error, stackTrace: stackTrace);

void i(String message, {dynamic error, StackTrace? trace}) =>
info(message, error: error, trace: trace);
void i(String message, {dynamic error, StackTrace? stackTrace}) =>
info(message, error: error, stackTrace: stackTrace);

void w(String message, {dynamic error, StackTrace? trace}) =>
warning(message, error: error, trace: trace);
void w(String message, {dynamic error, StackTrace? stackTrace}) =>
warning(message, error: error, stackTrace: stackTrace);

void e(String message, {dynamic error, StackTrace? trace}) =>
this.error(message, error: error, trace: trace);
void e(String message, {dynamic error, StackTrace? stackTrace}) =>
this.error(message, error: error, stackTrace: stackTrace);

void logNetworkError(NetworkError error);

Expand Down Expand Up @@ -131,24 +131,24 @@ class LoggerLogImpl extends Log {
LoggerLogImpl(this.logger, {required this.logNetworkInfo});

@override
void debug(String message, {dynamic error, StackTrace? trace}) =>
logger.d(message, error, trace);
void debug(String message, {dynamic error, StackTrace? stackTrace}) =>
logger.d(message, error: error, stackTrace: stackTrace);

@override
void error(String message, {error, StackTrace? trace}) =>
logger.e(message, error, trace);
void error(String message, {error, StackTrace? stackTrace}) =>
logger.e(message, error: error, stackTrace: stackTrace);

@override
void info(String message, {dynamic error, StackTrace? trace}) =>
logger.i(message, error, trace);
void info(String message, {dynamic error, StackTrace? stackTrace}) =>
logger.i(message, error: error, stackTrace: stackTrace);

@override
void verbose(String message, {dynamic error, StackTrace? trace}) =>
logger.v(message, error, trace);
void trace(String message, {dynamic error, StackTrace? stackTrace}) =>
logger.t(message, error: error, stackTrace: stackTrace);

@override
void warning(String message, {dynamic error, StackTrace? trace}) =>
logger.w(message, error, trace);
void warning(String message, {dynamic error, StackTrace? stackTrace}) =>
logger.w(message, error: error, stackTrace: stackTrace);

@override
void logNetworkError(NetworkError error) {
Expand Down Expand Up @@ -189,34 +189,34 @@ class LoggerLogImpl extends Log {
@visibleForTesting
class VoidLogger implements Log {
@override
void d(String message, {error, StackTrace? trace}) {}
void d(String message, {error, StackTrace? stackTrace}) {}

@override
void debug(String message, {error, StackTrace? trace}) {}
void debug(String message, {error, StackTrace? stackTrace}) {}

@override
void e(String message, {error, StackTrace? trace}) {}
void e(String message, {error, StackTrace? stackTrace}) {}

@override
void error(String message, {error, StackTrace? trace}) {}
void error(String message, {error, StackTrace? stackTrace}) {}

@override
void i(String message, {error, StackTrace? trace}) {}
void i(String message, {error, StackTrace? stackTrace}) {}

@override
void info(String message, {error, StackTrace? trace}) {}
void info(String message, {error, StackTrace? stackTrace}) {}

@override
void v(String message, {error, StackTrace? trace}) {}
void t(String message, {error, StackTrace? stackTrace}) {}

@override
void verbose(String message, {error, StackTrace? trace}) {}
void trace(String message, {error, StackTrace? stackTrace}) {}

@override
void w(String message, {error, StackTrace? trace}) {}
void w(String message, {error, StackTrace? stackTrace}) {}

@override
void warning(String message, {error, StackTrace? trace}) {}
void warning(String message, {error, StackTrace? stackTrace}) {}

@override
void logNetworkError(NetworkError error) {}
Expand All @@ -237,16 +237,17 @@ class PrefixLogger extends Log {
PrefixLogger(this._name, this._delegate);

@override
void debug(String message, {error, StackTrace? trace}) =>
_delegate.debug('[$_name] $message', error: error, trace: trace);
void debug(String message, {error, StackTrace? stackTrace}) => _delegate
.debug('[$_name] $message', error: error, stackTrace: stackTrace);

@override
void error(String message, {Object? error, StackTrace? trace}) =>
_delegate.error('[$_name] $message', error: error, trace: trace);
void error(String message, {Object? error, StackTrace? stackTrace}) =>
_delegate.error('[$_name] $message',
error: error, stackTrace: stackTrace);

@override
void info(String message, {error, StackTrace? trace}) =>
_delegate.info('[$_name] $message', error: error, trace: trace);
void info(String message, {error, StackTrace? stackTrace}) =>
_delegate.info('[$_name] $message', error: error, stackTrace: stackTrace);

@override
void logNetworkError(NetworkError error) => _delegate.logNetworkError(error);
Expand All @@ -260,10 +261,10 @@ class PrefixLogger extends Log {
_delegate.logNetworkResponse(response);

@override
void verbose(String message, {error, StackTrace? trace}) =>
_delegate.verbose('[$_name] $message', error: error, trace: trace);
void trace(String message, {error, StackTrace? stackTrace}) => _delegate
.trace('[$_name] $message', error: error, stackTrace: stackTrace);

@override
void warning(String message, {error, StackTrace? trace}) =>
_delegate.warning('[$_name] $message', error: error, trace: trace);
void warning(String message, {error, StackTrace? stackTrace}) => _delegate
.warning('[$_name] $message', error: error, stackTrace: stackTrace);
}
30 changes: 20 additions & 10 deletions lib/src/widget/touch_feedback/better_inkwell.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import 'package:flutter/material.dart';

class BetterInkwell extends StatefulWidget {
final Color color;
final Color colorHover;
final Color colorPress;
final Widget child;
final VoidCallback? onTap;
final BorderRadius? borderRadius;
final HitTestBehavior? behavior;

const BetterInkwell({
required this.child,
this.onTap,
this.behavior,
this.borderRadius,
this.colorHover = const Color(0x0A000000),
this.colorPress = const Color(0x1E000000),
this.color = Colors.transparent,
super.key,
});

Expand Down Expand Up @@ -98,14 +102,17 @@ class _BetterInkwellState extends State<BetterInkwell>
child!,
Positioned.fill(
child: IgnorePointer(
child: AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: _isTouched ? 1 : 0,
child: CustomPaint(
painter: _RipplePainter(
center: _touchPosition,
radius: _animationController!.value * speed,
color: widget.colorPress,
child: ClipRRect(
borderRadius: widget.borderRadius ?? BorderRadius.zero,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: _isTouched ? 1 : 0,
child: CustomPaint(
painter: _RipplePainter(
center: _touchPosition,
radius: _animationController!.value * speed,
color: widget.colorPress,
),
),
),
),
Expand All @@ -117,15 +124,18 @@ class _BetterInkwellState extends State<BetterInkwell>
duration: const Duration(milliseconds: 200),
opacity: _isTouched ? 1 : 0,
child: Container(
color: widget.colorHover,
decoration: BoxDecoration(
borderRadius: widget.borderRadius,
color: widget.colorHover,
),
),
),
),
),
],
),
child: Container(
color: Colors.transparent,
color: widget.color,
child: widget.child,
),
),
Expand Down
40 changes: 19 additions & 21 deletions lib/src/widget/touch_feedback/touch_feedback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,15 @@ class _TouchFeedBackState extends State<TouchFeedBack> {
@override
Widget build(BuildContext context) {
if ((!widget.forceIOS && context.isAndroidTheme) || widget.forceAndroid) {
return ClipRRect(
borderRadius: widget.borderRadius ?? BorderRadius.zero,
child: TouchFeedBackAndroid(
onClick: widget.onClick,
semanticsLabel: widget.semanticsLabel,
borderRadius: widget.borderRadius,
shapeBorder: widget.shapeBorder,
androidSplashColor: widget.androidSplashColor,
child: widget.child,
),
return TouchFeedBackAndroid(
onClick: widget.onClick,
semanticsLabel: widget.semanticsLabel,
borderRadius: widget.borderRadius,
color: widget.color,
elevation: widget.elevation,
shadowColor: widget.shadowColor,
shapeBorder: widget.shapeBorder,
child: widget.child,
);
}
return TouchFeedBackIOS(
Expand All @@ -71,22 +70,20 @@ class TouchFeedBackAndroid extends StatelessWidget {
final VoidCallback? onClick;
final String? semanticsLabel;
final Color color;
final double elevation;
final BorderRadius? borderRadius;
final double elevation;
final Color? shadowColor;
final ShapeBorder? shapeBorder;
final Color? androidSplashColor;

const TouchFeedBackAndroid({
required this.child,
required this.onClick,
this.semanticsLabel,
this.color = Colors.transparent,
this.elevation = 0,
this.borderRadius,
this.elevation = 0,
this.shadowColor,
this.shapeBorder,
this.androidSplashColor,
super.key,
});

Expand All @@ -95,14 +92,15 @@ class TouchFeedBackAndroid extends StatelessWidget {
return Semantics(
label: semanticsLabel,
button: true,
child: Material(
color: color,
shape: shapeBorder,
elevation: elevation,
shadowColor: shadowColor,
child: BetterInkwell(
borderRadius: borderRadius,
child: BetterInkwell(
onTap: onClick,
onTap: onClick,
child: Material(
color: color,
shape: shapeBorder,
elevation: elevation,
shadowColor: shadowColor,
borderRadius: borderRadius,
child: child,
),
),
Expand Down
Loading

0 comments on commit 7358ce9

Please sign in to comment.