mirror of
https://github.com/Livinglist/Hacki.git
synced 2025-08-06 18:24:42 +08:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
c6e0461857 | |||
30ca356dc8 |
@ -2,4 +2,5 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
||||||
|
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
Normal file
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
Normal file
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 940 B |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
Normal file
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
@ -24,6 +24,6 @@ subprojects {
|
|||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
|||||||
abstract class InAppReviewPlatform extends PlatformInterface {
|
abstract class InAppReviewPlatform extends PlatformInterface {
|
||||||
InAppReviewPlatform() : super(token: _token);
|
InAppReviewPlatform() : super(token: _token);
|
||||||
|
|
||||||
static InAppReviewPlatform _instance = MethodChannelInAppReview();
|
static InAppReviewPlatform _instance =
|
||||||
|
MethodChannelInAppReview() as InAppReviewPlatform;
|
||||||
|
|
||||||
static final Object _token = Object();
|
static final Object _token = Object();
|
||||||
|
|
||||||
|
@ -156,4 +156,4 @@ SPEC CHECKSUMS:
|
|||||||
|
|
||||||
PODFILE CHECKSUM: d28e9a1c7bee335d05ddd795703aad5bf05bb937
|
PODFILE CHECKSUM: d28e9a1c7bee335d05ddd795703aad5bf05bb937
|
||||||
|
|
||||||
COCOAPODS: 1.11.3
|
COCOAPODS: 1.12.0
|
||||||
|
@ -23,6 +23,12 @@ class SearchState extends Equatable {
|
|||||||
final SearchStatus status;
|
final SearchStatus status;
|
||||||
final SearchParams params;
|
final SearchParams params;
|
||||||
|
|
||||||
|
bool get hasDateFilter =>
|
||||||
|
params.filters.whereType<DateTimeRangeFilter>().isNotEmpty;
|
||||||
|
|
||||||
|
DateTimeRangeFilter? get dateFilter =>
|
||||||
|
params.filters.whereType<DateTimeRangeFilter>().singleOrNull;
|
||||||
|
|
||||||
SearchState copyWith({
|
SearchState copyWith({
|
||||||
List<Item>? results,
|
List<Item>? results,
|
||||||
SearchStatus? status,
|
SearchStatus? status,
|
||||||
|
@ -30,14 +30,27 @@ class DateTimeRangeFilter implements NumericFilter {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get query {
|
String get query {
|
||||||
|
if (startTime == null || endTime == null) return '';
|
||||||
|
|
||||||
final int? startTimestamp = startTime == null
|
final int? startTimestamp = startTime == null
|
||||||
? null
|
? null
|
||||||
: startTime!.toUtc().millisecondsSinceEpoch ~/ 1000;
|
: startTime!.toUtc().millisecondsSinceEpoch ~/ 1000;
|
||||||
final int? endTimestamp = endTime == null
|
int? endTimestamp = endTime == null
|
||||||
? null
|
? null
|
||||||
: endTime!.toUtc().millisecondsSinceEpoch ~/ 1000;
|
: endTime!.toUtc().millisecondsSinceEpoch ~/ 1000;
|
||||||
|
|
||||||
|
if (startTimestamp == endTimestamp) {
|
||||||
|
endTimestamp = startTime!
|
||||||
|
.add(const Duration(hours: 24))
|
||||||
|
.toUtc()
|
||||||
|
.millisecondsSinceEpoch ~/
|
||||||
|
1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startTimestamp == null || endTimestamp == null) return '';
|
||||||
|
|
||||||
final String query =
|
final String query =
|
||||||
'''${startTimestamp == null ? '' : 'created_at_i>$startTimestamp'},${endTimestamp == null ? '' : 'created_at_i<$endTimestamp'}''';
|
'''created_at_i>=$startTimestamp, created_at_i<=$endTimestamp''';
|
||||||
|
|
||||||
if (query.endsWith(',')) {
|
if (query.endsWith(',')) {
|
||||||
return query.replaceFirst(',', '');
|
return query.replaceFirst(',', '');
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_fadein/flutter_fadein.dart';
|
import 'package:flutter_fadein/flutter_fadein.dart';
|
||||||
import 'package:hacki/cubits/cubits.dart';
|
import 'package:hacki/cubits/cubits.dart';
|
||||||
@ -28,7 +29,39 @@ class SearchScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _SearchScreenState extends State<SearchScreen> {
|
class _SearchScreenState extends State<SearchScreen> {
|
||||||
final RefreshController refreshController = RefreshController();
|
final RefreshController refreshController = RefreshController();
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
final Debouncer debouncer = Debouncer(delay: const Duration(seconds: 1));
|
final Debouncer debouncer = Debouncer(delay: const Duration(seconds: 1));
|
||||||
|
bool showChips = true;
|
||||||
|
bool shouldOffStageChips = false;
|
||||||
|
|
||||||
|
static const Duration chipsAnimationDuration = Duration(milliseconds: 300);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
scrollController.addListener(() {
|
||||||
|
if (scrollController.position.userScrollDirection ==
|
||||||
|
ScrollDirection.reverse &&
|
||||||
|
showChips) {
|
||||||
|
setState(() {
|
||||||
|
showChips = false;
|
||||||
|
});
|
||||||
|
} else if (scrollController.position.userScrollDirection ==
|
||||||
|
ScrollDirection.forward &&
|
||||||
|
!showChips) {
|
||||||
|
setState(() {
|
||||||
|
showChips = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
refreshController.dispose();
|
||||||
|
scrollController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -72,6 +105,85 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: Dimens.pt6,
|
height: Dimens.pt6,
|
||||||
),
|
),
|
||||||
|
AnimatedCrossFade(
|
||||||
|
duration: chipsAnimationDuration,
|
||||||
|
crossFadeState: showChips
|
||||||
|
? CrossFadeState.showSecond
|
||||||
|
: CrossFadeState.showFirst,
|
||||||
|
firstChild: SizedBox.fromSize(),
|
||||||
|
secondChild: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
if (state.hasDateFilter &&
|
||||||
|
state.dateFilter?.startTime != null &&
|
||||||
|
state.dateFilter?.endTime != null)
|
||||||
|
SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
const SizedBox(
|
||||||
|
width: Dimens.pt8,
|
||||||
|
),
|
||||||
|
DateTimeShortcutChip.dayBefore(
|
||||||
|
onDateTimeRangeUpdated: context
|
||||||
|
.read<SearchCubit>()
|
||||||
|
.onDateTimeRangeUpdated,
|
||||||
|
startDate: state.dateFilter!.startTime!,
|
||||||
|
endDate: state.dateFilter!.endTime!,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: Dimens.pt8,
|
||||||
|
),
|
||||||
|
DateTimeShortcutChip.dayAfter(
|
||||||
|
onDateTimeRangeUpdated: context
|
||||||
|
.read<SearchCubit>()
|
||||||
|
.onDateTimeRangeUpdated,
|
||||||
|
startDate: state.dateFilter!.startTime!,
|
||||||
|
endDate: state.dateFilter!.endTime!,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: Dimens.pt8,
|
||||||
|
),
|
||||||
|
DateTimeShortcutChip.weekBefore(
|
||||||
|
onDateTimeRangeUpdated: context
|
||||||
|
.read<SearchCubit>()
|
||||||
|
.onDateTimeRangeUpdated,
|
||||||
|
startDate: state.dateFilter!.startTime!,
|
||||||
|
endDate: state.dateFilter!.endTime!,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: Dimens.pt8,
|
||||||
|
),
|
||||||
|
DateTimeShortcutChip.weekAfter(
|
||||||
|
onDateTimeRangeUpdated: context
|
||||||
|
.read<SearchCubit>()
|
||||||
|
.onDateTimeRangeUpdated,
|
||||||
|
startDate: state.dateFilter!.startTime!,
|
||||||
|
endDate: state.dateFilter!.endTime!,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: Dimens.pt8,
|
||||||
|
),
|
||||||
|
DateTimeShortcutChip.monthBefore(
|
||||||
|
onDateTimeRangeUpdated: context
|
||||||
|
.read<SearchCubit>()
|
||||||
|
.onDateTimeRangeUpdated,
|
||||||
|
startDate: state.dateFilter!.startTime!,
|
||||||
|
endDate: state.dateFilter!.endTime!,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: Dimens.pt8,
|
||||||
|
),
|
||||||
|
DateTimeShortcutChip.monthAfter(
|
||||||
|
onDateTimeRangeUpdated: context
|
||||||
|
.read<SearchCubit>()
|
||||||
|
.onDateTimeRangeUpdated,
|
||||||
|
startDate: state.dateFilter!.startTime!,
|
||||||
|
endDate: state.dateFilter!.endTime!,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -80,7 +192,9 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||||||
width: Dimens.pt8,
|
width: Dimens.pt8,
|
||||||
),
|
),
|
||||||
DateTimeRangeFilterChip(
|
DateTimeRangeFilterChip(
|
||||||
filter: state.params.get<DateTimeRangeFilter>(),
|
filter: state.dateFilter,
|
||||||
|
initialStartDate: state.dateFilter?.startTime,
|
||||||
|
initialEndDate: state.dateFilter?.endTime,
|
||||||
onDateTimeRangeUpdated: context
|
onDateTimeRangeUpdated: context
|
||||||
.read<SearchCubit>()
|
.read<SearchCubit>()
|
||||||
.onDateTimeRangeUpdated,
|
.onDateTimeRangeUpdated,
|
||||||
@ -93,8 +207,9 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||||||
),
|
),
|
||||||
PostedByFilterChip(
|
PostedByFilterChip(
|
||||||
filter: state.params.get<PostedByFilter>(),
|
filter: state.params.get<PostedByFilter>(),
|
||||||
onChanged:
|
onChanged: context
|
||||||
context.read<SearchCubit>().onPostedByChanged,
|
.read<SearchCubit>()
|
||||||
|
.onPostedByChanged,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: Dimens.pt8,
|
width: Dimens.pt8,
|
||||||
@ -133,8 +248,9 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||||||
width: Dimens.pt8,
|
width: Dimens.pt8,
|
||||||
),
|
),
|
||||||
CustomChip(
|
CustomChip(
|
||||||
onSelected: (_) =>
|
onSelected: (_) => context
|
||||||
context.read<SearchCubit>().onToggled(filter),
|
.read<SearchCubit>()
|
||||||
|
.onToggled(filter),
|
||||||
selected: context
|
selected: context
|
||||||
.read<SearchCubit>()
|
.read<SearchCubit>()
|
||||||
.state
|
.state
|
||||||
@ -147,6 +263,9 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
if (state.status == SearchStatus.loading &&
|
if (state.status == SearchStatus.loading &&
|
||||||
state.results.isEmpty) ...<Widget>[
|
state.results.isEmpty) ...<Widget>[
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@ -200,11 +319,15 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
controller: refreshController,
|
controller: refreshController,
|
||||||
|
scrollController: scrollController,
|
||||||
onRefresh: () {},
|
onRefresh: () {},
|
||||||
onLoading: () {
|
onLoading: () {
|
||||||
context.read<SearchCubit>().loadMore();
|
context.read<SearchCubit>().loadMore();
|
||||||
},
|
},
|
||||||
child: ListView(
|
child: ListView(
|
||||||
|
physics: state.results.isEmpty
|
||||||
|
? const NeverScrollableScrollPhysics()
|
||||||
|
: null,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
...state.results
|
...state.results
|
||||||
.map(
|
.map(
|
||||||
|
@ -6,12 +6,16 @@ import 'package:intl/intl.dart';
|
|||||||
class DateTimeRangeFilterChip extends StatelessWidget {
|
class DateTimeRangeFilterChip extends StatelessWidget {
|
||||||
const DateTimeRangeFilterChip({
|
const DateTimeRangeFilterChip({
|
||||||
required this.filter,
|
required this.filter,
|
||||||
|
required this.initialStartDate,
|
||||||
|
required this.initialEndDate,
|
||||||
required this.onDateTimeRangeUpdated,
|
required this.onDateTimeRangeUpdated,
|
||||||
required this.onDateTimeRangeRemoved,
|
required this.onDateTimeRangeRemoved,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
final DateTimeRangeFilter? filter;
|
final DateTimeRangeFilter? filter;
|
||||||
|
final DateTime? initialStartDate;
|
||||||
|
final DateTime? initialEndDate;
|
||||||
final void Function(DateTime, DateTime) onDateTimeRangeUpdated;
|
final void Function(DateTime, DateTime) onDateTimeRangeUpdated;
|
||||||
final VoidCallback onDateTimeRangeRemoved;
|
final VoidCallback onDateTimeRangeRemoved;
|
||||||
|
|
||||||
@ -25,6 +29,9 @@ class DateTimeRangeFilterChip extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
firstDate: DateTime.now().subtract(const Duration(days: 20 * 365)),
|
firstDate: DateTime.now().subtract(const Duration(days: 20 * 365)),
|
||||||
lastDate: DateTime.now(),
|
lastDate: DateTime.now(),
|
||||||
|
initialDateRange: initialStartDate != null && initialEndDate != null
|
||||||
|
? DateTimeRange(start: initialStartDate!, end: initialEndDate!)
|
||||||
|
: null,
|
||||||
).then((DateTimeRange? range) {
|
).then((DateTimeRange? range) {
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
onDateTimeRangeUpdated(range.start, range.end);
|
onDateTimeRangeUpdated(range.start, range.end);
|
||||||
@ -34,11 +41,22 @@ class DateTimeRangeFilterChip extends StatelessWidget {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
selected: filter != null,
|
selected: filter != null,
|
||||||
label:
|
label: _label,
|
||||||
'''from ${_formatDateTime(filter?.startTime) ?? 'X'} to ${_formatDateTime(filter?.endTime) ?? 'Y'}''',
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get _label {
|
||||||
|
final DateTime? start = filter?.startTime;
|
||||||
|
final DateTime? end = filter?.endTime;
|
||||||
|
if (start == null && end == null) {
|
||||||
|
return '''from X to Y''';
|
||||||
|
} else if (start == end) {
|
||||||
|
return '''from ${_formatDateTime(start)}''';
|
||||||
|
} else {
|
||||||
|
return '''from ${_formatDateTime(start)} to ${_formatDateTime(end)}''';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static String? _formatDateTime(DateTime? dateTime) {
|
static String? _formatDateTime(DateTime? dateTime) {
|
||||||
if (dateTime == null) return null;
|
if (dateTime == null) return null;
|
||||||
|
|
||||||
|
88
lib/screens/search/widgets/date_time_shortcut_chip.dart
Normal file
88
lib/screens/search/widgets/date_time_shortcut_chip.dart
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hacki/screens/search/widgets/date_time_range_filter_chip.dart';
|
||||||
|
import 'package:hacki/screens/widgets/widgets.dart' show CustomChip;
|
||||||
|
|
||||||
|
typedef Calculator = DateTime Function(DateTime);
|
||||||
|
|
||||||
|
/// A set of chips that perform addition or subtraction on the date selected
|
||||||
|
/// by [DateTimeRangeFilterChip]
|
||||||
|
class DateTimeShortcutChip extends StatelessWidget {
|
||||||
|
const DateTimeShortcutChip({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
required this.label,
|
||||||
|
required Calculator calculator,
|
||||||
|
super.key,
|
||||||
|
}) : _calculator = calculator;
|
||||||
|
|
||||||
|
DateTimeShortcutChip.dayBefore({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
super.key,
|
||||||
|
}) : label = '- day',
|
||||||
|
_calculator =
|
||||||
|
((DateTime date) => date.subtract(const Duration(hours: 24)));
|
||||||
|
|
||||||
|
DateTimeShortcutChip.dayAfter({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
super.key,
|
||||||
|
}) : label = '+ day',
|
||||||
|
_calculator = ((DateTime date) => date.add(const Duration(hours: 24)));
|
||||||
|
|
||||||
|
DateTimeShortcutChip.weekBefore({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
super.key,
|
||||||
|
}) : label = '- week',
|
||||||
|
_calculator =
|
||||||
|
((DateTime date) => date.subtract(const Duration(days: 7)));
|
||||||
|
|
||||||
|
DateTimeShortcutChip.weekAfter({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
super.key,
|
||||||
|
}) : label = '+ week',
|
||||||
|
_calculator = ((DateTime date) => date.add(const Duration(days: 7)));
|
||||||
|
|
||||||
|
DateTimeShortcutChip.monthBefore({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
super.key,
|
||||||
|
}) : label = '- 30 days',
|
||||||
|
_calculator =
|
||||||
|
((DateTime date) => date.subtract(const Duration(days: 30)));
|
||||||
|
|
||||||
|
DateTimeShortcutChip.monthAfter({
|
||||||
|
required this.onDateTimeRangeUpdated,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
super.key,
|
||||||
|
}) : label = '+ 30 days',
|
||||||
|
_calculator = ((DateTime date) => date.add(const Duration(days: 30)));
|
||||||
|
|
||||||
|
final void Function(DateTime, DateTime) onDateTimeRangeUpdated;
|
||||||
|
final DateTime startDate;
|
||||||
|
final DateTime endDate;
|
||||||
|
final String label;
|
||||||
|
final Calculator _calculator;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CustomChip(
|
||||||
|
onSelected: (bool value) {
|
||||||
|
final DateTime updatedStartDate = _calculator(startDate);
|
||||||
|
final DateTime updatedEndDate = _calculator(endDate);
|
||||||
|
onDateTimeRangeUpdated(updatedStartDate, updatedEndDate);
|
||||||
|
},
|
||||||
|
selected: false,
|
||||||
|
label: label,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export 'custom_range_filter_chip.dart';
|
export 'custom_range_filter_chip.dart';
|
||||||
export 'date_time_range_filter_chip.dart';
|
export 'date_time_range_filter_chip.dart';
|
||||||
|
export 'date_time_shortcut_chip.dart';
|
||||||
export 'posted_by_filter_chip.dart';
|
export 'posted_by_filter_chip.dart';
|
||||||
|
@ -1390,4 +1390,4 @@ packages:
|
|||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.0.0 <4.0.0"
|
dart: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.10.1"
|
flutter: ">=3.10.2"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
name: hacki
|
name: hacki
|
||||||
description: A Hacker News reader.
|
description: A Hacker News reader.
|
||||||
version: 1.6.0+110
|
version: 1.7.0+111
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: "3.10.1"
|
flutter: "3.10.2"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
adaptive_theme: ^3.2.0
|
adaptive_theme: ^3.2.0
|
||||||
|
Submodule submodules/flutter updated: d3d8effc68...9cd3d0d9ff
Reference in New Issue
Block a user