Skip to content

Commit

Permalink
Copy pasted the SmoothStarRating package.
Browse files Browse the repository at this point in the history
Switched to flutter_user_agentx
  • Loading branch information
Wolfteam committed Apr 30, 2021
1 parent 3ee7206 commit 41d4d04
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/infrastructure/device_info_service.dart
@@ -1,7 +1,7 @@
import 'dart:io';

import 'package:device_info/device_info.dart';
import 'package:flutter_user_agent/flutter_user_agent.dart';
import 'package:flutter_user_agentx/flutter_user_agent.dart';
import 'package:genshindb/domain/services/device_info_service.dart';
import 'package:package_info/package_info.dart';

Expand Down
2 changes: 1 addition & 1 deletion lib/presentation/shared/rarity_rating.dart
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:genshindb/presentation/shared/smooth_star_rating.dart';

class RarityRating extends StatelessWidget {
final int rarity;
Expand Down
232 changes: 232 additions & 0 deletions lib/presentation/shared/smooth_star_rating.dart
@@ -0,0 +1,232 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

typedef RatingChangeCallback = void Function(double rating);

class SmoothStarRating extends StatefulWidget {
final int starCount;
final double rating;
final RatingChangeCallback onRated;
final Color color;
final Color borderColor;
final double size;
final bool allowHalfRating;
final IconData filledIconData;
final IconData halfFilledIconData;
final IconData defaultIconData; //this is needed only when having fullRatedIconData && halfRatedIconData
final double spacing;
final bool isReadOnly;

SmoothStarRating({
this.starCount = 5,
this.isReadOnly = false,
this.spacing = 0.0,
this.rating = 0.0,
this.defaultIconData = Icons.star_border,
this.onRated,
this.color,
this.borderColor,
this.size = 25,
this.filledIconData = Icons.star,
this.halfFilledIconData = Icons.star_half,
this.allowHalfRating = true,
}) {
assert(this.rating != null);
}

@override
_SmoothStarRatingState createState() => _SmoothStarRatingState();
}

class _SmoothStarRatingState extends State<SmoothStarRating> {
final double halfStarThreshold = 0.53; //half star value starts from this number

//tracks for user tapping on this widget
bool isWidgetTapped = false;
double currentRating;
Timer debounceTimer;

@override
void initState() {
currentRating = widget.rating;
super.initState();
}

@override
void dispose() {
debounceTimer?.cancel();
debounceTimer = null;
super.dispose();
}

@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: Wrap(
alignment: WrapAlignment.start, spacing: widget.spacing, children: List.generate(widget.starCount, (index) => buildStar(context, index))),
);
}

Widget buildStar(BuildContext context, int index) {
Icon icon;
if (index >= currentRating) {
icon = Icon(
widget.defaultIconData,
color: widget.borderColor ?? Theme.of(context).primaryColor,
size: widget.size,
);
} else if (index > currentRating - (widget.allowHalfRating ? halfStarThreshold : 1.0) && index < currentRating) {
icon = Icon(
widget.halfFilledIconData,
color: widget.color ?? Theme.of(context).primaryColor,
size: widget.size,
);
} else {
icon = Icon(
widget.filledIconData,
color: widget.color ?? Theme.of(context).primaryColor,
size: widget.size,
);
}
final Widget star = widget.isReadOnly
? icon
: kIsWeb
? MouseRegion(
onExit: (event) {
if (widget.onRated != null && !isWidgetTapped) {
//reset to zero only if rating is not set by user
setState(() {
currentRating = 0;
});
}
},
onEnter: (event) {
isWidgetTapped = false; //reset
},
onHover: (event) {
RenderBox box = context.findRenderObject() as RenderBox;
var _pos = box.globalToLocal(event.position);
var i = _pos.dx / widget.size;
var newRating = widget.allowHalfRating ? i : i.round().toDouble();
if (newRating > widget.starCount) {
newRating = widget.starCount.toDouble();
}
if (newRating < 0) {
newRating = 0.0;
}
setState(() {
currentRating = newRating;
});
},
child: GestureDetector(
onTapDown: (detail) {
isWidgetTapped = true;

RenderBox box = context.findRenderObject() as RenderBox;
var _pos = box.globalToLocal(detail.globalPosition);
var i = ((_pos.dx - widget.spacing) / widget.size);
var newRating = widget.allowHalfRating ? i : i.round().toDouble();
if (newRating > widget.starCount) {
newRating = widget.starCount.toDouble();
}
if (newRating < 0) {
newRating = 0.0;
}
setState(() {
currentRating = newRating;
});
if (widget.onRated != null) {
widget.onRated(normalizeRating(currentRating));
}
},
onHorizontalDragUpdate: (dragDetails) {
isWidgetTapped = true;

RenderBox box = context.findRenderObject() as RenderBox;
var _pos = box.globalToLocal(dragDetails.globalPosition);
var i = _pos.dx / widget.size;
var newRating = widget.allowHalfRating ? i : i.round().toDouble();
if (newRating > widget.starCount) {
newRating = widget.starCount.toDouble();
}
if (newRating < 0) {
newRating = 0.0;
}
setState(() {
currentRating = newRating;
});
debounceTimer?.cancel();
debounceTimer = Timer(Duration(milliseconds: 100), () {
if (widget.onRated != null) {
currentRating = normalizeRating(newRating);
widget.onRated(currentRating);
}
});
},
child: icon,
),
)
: GestureDetector(
onTapDown: (detail) {
RenderBox box = context.findRenderObject() as RenderBox;
var _pos = box.globalToLocal(detail.globalPosition);
var i = ((_pos.dx - widget.spacing) / widget.size);
var newRating = widget.allowHalfRating ? i : i.round().toDouble();
if (newRating > widget.starCount) {
newRating = widget.starCount.toDouble();
}
if (newRating < 0) {
newRating = 0.0;
}
newRating = normalizeRating(newRating);
setState(() {
currentRating = newRating;
});
},
onTapUp: (e) {
if (widget.onRated != null) widget.onRated(currentRating);
},
onHorizontalDragUpdate: (dragDetails) {
RenderBox box = context.findRenderObject() as RenderBox;
var _pos = box.globalToLocal(dragDetails.globalPosition);
var i = _pos.dx / widget.size;
var newRating = widget.allowHalfRating ? i : i.round().toDouble();
if (newRating > widget.starCount) {
newRating = widget.starCount.toDouble();
}
if (newRating < 0) {
newRating = 0.0;
}
setState(() {
currentRating = newRating;
});
debounceTimer?.cancel();
debounceTimer = Timer(Duration(milliseconds: 100), () {
if (widget.onRated != null) {
currentRating = normalizeRating(newRating);
widget.onRated(currentRating);
}
});
},
child: icon,
);

return star;
}

double normalizeRating(double newRating) {
var k = newRating - newRating.floor();
if (k != 0) {
//half stars
if (k >= halfStarThreshold) {
newRating = newRating.floor() + 1.0;
} else {
newRating = newRating.floor() + 0.5;
}
}
return newRating;
}
}
15 changes: 4 additions & 11 deletions pubspec.lock
Expand Up @@ -296,13 +296,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_user_agent:
flutter_user_agentx:
dependency: "direct main"
description:
name: flutter_user_agent
name: flutter_user_agentx
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
version: "1.2.4"
flutter_web_plugins:
dependency: transitive
description: flutter
Expand Down Expand Up @@ -733,13 +733,6 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
smooth_star_rating:
dependency: "direct main"
description:
name: smooth_star_rating
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
source_gen:
dependency: transitive
description:
Expand Down Expand Up @@ -931,4 +924,4 @@ packages:
version: "3.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.24.0-6.0.pre"
flutter: ">=2.0.0"
3 changes: 1 addition & 2 deletions pubspec.yaml
Expand Up @@ -33,7 +33,7 @@ dependencies:
sdk: flutter
flutter_slidable: ^0.6.0
flutter_staggered_grid_view: ^0.4.0
flutter_user_agent: ^1.2.2
flutter_user_agentx: ^1.2.4
flutter_webview_plugin: ^0.3.11
fluttertoast: 8.0.3
freezed_annotation: ^0.12.0
Expand All @@ -52,7 +52,6 @@ dependencies:
rate_my_app: ^1.1.0+1
screenshot: ^0.3.0
shared_preferences: ^2.0.5
smooth_star_rating: 1.1.1
sprintf: ^6.0.0
transparent_image: 2.0.0
tuple: ^2.0.0
Expand Down

0 comments on commit 41d4d04

Please sign in to comment.