Skip to content
1 change: 1 addition & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: aa9c826e174e713c4dad1b0d2110be4d87591fc5

COCOAPODS: 1.16.2

25 changes: 25 additions & 0 deletions lib/core/models/sort_option.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
enum SortOption {
nameAsc,
nameDesc,
dateModifiedNewest,
dateModifiedOldest,
dateCreatedNewest,
dateCreatedOldest;

String get label {
switch (this) {
case SortOption.nameAsc:
return 'Name (A to Z)';
case SortOption.nameDesc:
return 'Name (Z to A)';
case SortOption.dateModifiedNewest:
return 'Last Modified (Newest)';
case SortOption.dateModifiedOldest:
return 'Last Modified (Oldest)';
case SortOption.dateCreatedNewest:
return 'Date Created (Newest)';
case SortOption.dateCreatedOldest:
return 'Date Created (Oldest)';
}
}
}
8 changes: 8 additions & 0 deletions lib/core/providers/object/search_filter_sort_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:paintroid/core/models/sort_option.dart';

final searchActiveProvider = StateProvider<bool>((ref) => false);
final searchQueryProvider = StateProvider<String>((ref) => '');
final sortOptionProvider = StateProvider<SortOption>(
(ref) => SortOption.dateModifiedNewest,
);
80 changes: 80 additions & 0 deletions lib/ui/pages/landing_page/components/search_text_field.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:paintroid/core/models/sort_option.dart';
import 'package:paintroid/ui/theme/theme.dart';

class SearchTextField extends StatelessWidget {
final TextEditingController controller;
final FocusNode focusNode;
final ValueChanged<String> onChanged;
final SortOption currentSortOption;
final ValueChanged<SortOption> onSortOptionSelected;

const SearchTextField({
super.key,
required this.controller,
required this.focusNode,
required this.onChanged,
required this.currentSortOption,
required this.onSortOptionSelected,
});

@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: TextField(
controller: controller,
focusNode: focusNode,
autofocus: true,
style: TextStyle(
color: PaintroidTheme.of(context).onSurfaceColor,
),
decoration: InputDecoration(
hintText: 'Search projects...',
hintStyle: TextStyle(
color:
PaintroidTheme.of(context).onSurfaceColor.withOpacity(0.6),
),
border: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
),
onChanged: onChanged,
),
),
PopupMenuButton<SortOption>(
icon: Icon(
Icons.sort,
color: PaintroidTheme.of(context).onSurfaceColor,
),
tooltip: 'Sort options',
onSelected: onSortOptionSelected,
itemBuilder: (context) => SortOption.values
.map(
(option) => PopupMenuItem<SortOption>(
value: option,
child: Row(
children: [
Icon(
option == currentSortOption
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
size: 18,
),
const SizedBox(width: 8),
Flexible(
child: Text(
option.label,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
)
.toList(),
),
],
);
}
}
28 changes: 28 additions & 0 deletions lib/ui/pages/landing_page/components/search_toggle_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';

class SearchToggleButton extends StatelessWidget {
final bool isSearchActive;
final VoidCallback onSearchStart;
final VoidCallback onSearchEnd;

const SearchToggleButton({
super.key,
required this.isSearchActive,
required this.onSearchStart,
required this.onSearchEnd,
});

@override
Widget build(BuildContext context) {
if (isSearchActive) {
return IconButton(
icon: const Icon(Icons.close),
onPressed: onSearchEnd,
);
}
return IconButton(
icon: const Icon(Icons.search),
onPressed: onSearchStart,
);
}
}
Loading
Loading