Skip to content

Commit

Permalink
Customizable_sort_order (#116) (#117)
Browse files Browse the repository at this point in the history
Added PopupMenu for displaying sorting options

Co-authored-by: Sanketh B K <[email protected]>
  • Loading branch information
github-actions[bot] and SankethBK authored Oct 23, 2023
1 parent 17809ce commit 4c222cd
Show file tree
Hide file tree
Showing 17 changed files with 374 additions and 20 deletions.
8 changes: 7 additions & 1 deletion lib/app/themes/coral_bubble_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ class CoralBubble {
),
// used for dialogs in flutter_quill
canvasColor: Colors.white.withOpacity(0.9),

popupMenuTheme: PopupMenuThemeData(
color: Colors.white.withOpacity(0.9), // Set the background color
textStyle: const TextStyle(color: Colors.black), // Set text color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
// theme extensions
extensions: <ThemeExtension<dynamic>>{
AuthPageThemeExtensions(
Expand Down
7 changes: 7 additions & 0 deletions lib/app/themes/cosmic_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ class Cosmic {
),
// used for dialogs in flutter_quill
canvasColor: Colors.black.withOpacity(0.7),
popupMenuTheme: PopupMenuThemeData(
color: Colors.black.withOpacity(0.9), // Set the background color
textStyle: const TextStyle(color: Colors.white), // Set text color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
// theme extensions
extensions: <ThemeExtension<dynamic>>{
AuthPageThemeExtensions(
Expand Down
7 changes: 7 additions & 0 deletions lib/app/themes/lush_green_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ class LushGreen {
),
// used for dialogs in flutter_quill
canvasColor: Colors.black.withOpacity(0.7),
popupMenuTheme: PopupMenuThemeData(
color: Colors.black.withOpacity(0.9), // Set the background color
textStyle: const TextStyle(color: Colors.white), // Set text color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
// theme extensions
extensions: <ThemeExtension<dynamic>>{
AuthPageThemeExtensions(
Expand Down
7 changes: 7 additions & 0 deletions lib/app/themes/plain_dark.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ class PlainDark {
),
// used for dialogs in flutter_quill
canvasColor: Colors.black.withOpacity(0.7),
popupMenuTheme: PopupMenuThemeData(
color: Colors.black.withOpacity(0.9), // Set the background color
textStyle: const TextStyle(color: Colors.white), // Set text color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
// theme extensions
extensions: <ThemeExtension<dynamic>>{
AuthPageThemeExtensions(
Expand Down
5 changes: 4 additions & 1 deletion lib/core/dependency_injection/injection_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ Future<void> init() async {
//* Blocs
sl.registerLazySingleton(() => NotesBloc(notesRepository: sl()));
sl.registerLazySingleton(() => NotesFetchCubit(
notesRepository: sl(), notesBloc: sl(), noteSyncCubit: sl()));
notesRepository: sl(),
notesBloc: sl(),
noteSyncCubit: sl(),
userConfigCubit: sl()));
sl.registerLazySingleton(() => SelectableListCubit());

//* FEATURE: sync
Expand Down
3 changes: 2 additions & 1 deletion lib/core/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
if (state is NotesFetchDummyState) {
notesFetchCubit.fetchNotes();
return const Center(child: CircularProgressIndicator());
} else if (state is NotesFetchSuccessful) {
} else if (state is NotesFetchSuccessful ||
state is NotesSortSuccessful) {
return ListView.builder(
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
Expand Down
56 changes: 49 additions & 7 deletions lib/core/widgets/home_page_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:dairy_app/core/widgets/date_input_field.dart';
import 'package:dairy_app/core/widgets/glass_dialog.dart';
import 'package:dairy_app/core/widgets/glassmorphism_cover.dart';
import 'package:dairy_app/core/widgets/submit_button.dart';
import 'package:dairy_app/features/auth/data/models/user_config_model.dart';
import 'package:dairy_app/features/notes/presentation/bloc/notes/notes_bloc.dart';
import 'package:dairy_app/features/notes/presentation/bloc/notes_fetch/notes_fetch_cubit.dart';
import 'package:dairy_app/features/notes/presentation/bloc/selectable_list/selectable_list_cubit.dart';
Expand Down Expand Up @@ -148,6 +149,8 @@ class Action extends StatelessWidget {
@override
Widget build(BuildContext context) {
final selectableListCubit = BlocProvider.of<SelectableListCubit>(context);
final notesFetchCubit = BlocProvider.of<NotesFetchCubit>(context);

return BlocBuilder<SelectableListCubit, SelectableListState>(
builder: (context, state) {
Widget getSuitableWidget() {
Expand All @@ -174,13 +177,52 @@ class Action extends StatelessWidget {
],
);
} else {
return Padding(
key: const ValueKey("search icon"),
padding: const EdgeInsets.only(right: 13.0),
child: IconButton(
icon: const Icon(Icons.search),
onPressed: openSearchAppBar,
),
return Row(
children: [
Padding(
key: const ValueKey("search icon"),
padding: const EdgeInsets.only(right: 5.0),
child: IconButton(
icon: const Icon(Icons.search),
onPressed: openSearchAppBar,
),
),
Padding(
padding: const EdgeInsets.only(right: 13.0),
child: PopupMenuButton<NoteSortType>(
key: const ValueKey("sort icon"),
icon: const Icon(
Icons.sort,
color: Colors.white,
),
onSelected: (NoteSortType value) async {
await notesFetchCubit.setNoteSortType(value);
},
itemBuilder: (BuildContext context) {
return [
PopupMenuItem<NoteSortType>(
value: NoteSortType.sortByLatestFirst,
child: Text(
S.current.sortByLatestFirst,
),
),
PopupMenuItem<NoteSortType>(
value: NoteSortType.sortByOldestFirst,
child: Text(
S.current.sortByOldestFirst,
),
),
PopupMenuItem<NoteSortType>(
value: NoteSortType.sortByAtoZ,
child: Text(
S.current.sortByAtoZ,
),
),
];
},
),
),
],
);
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/features/auth/core/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class UserConfigConstants {
static String isAutoSaveEnabled = "is_auto_save_enabled";
static String isDailyReminderEnabled = "is_daily_reminder_enabled";
static String reminderTime = "reminder_time";
static String noteSortType = "note_sort_type";
}

class SyncConstants {
Expand Down
35 changes: 33 additions & 2 deletions lib/features/auth/data/models/user_config_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@ import 'package:dairy_app/features/auth/core/constants.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';

enum NoteSortType {
sortByLatestFirst("sortByLatestFirst"),
sortByOldestFirst("sortByOldestFirst"),
sortByAtoZ("sortByAtoZ");

const NoteSortType(this.text);

factory NoteSortType.fromStringValue(String stringValue) {
switch (stringValue) {
case 'sortByLatestFirst':
return NoteSortType.sortByLatestFirst;
case 'sortByOldestFirst':
return NoteSortType.sortByOldestFirst;
case 'sortByAtoZ':
return NoteSortType.sortByAtoZ;
default:
throw Exception('Invalid NoteSortType value: $stringValue');
}
}
final String text;
}

/// class to store non-critical properties of user
/// it is stored apart from user table, which stores critical properties of user
class UserConfigModel extends Equatable {
Expand All @@ -16,6 +38,7 @@ class UserConfigModel extends Equatable {
final bool? isAutoSaveEnabled;
final bool? isDailyReminderEnabled;
final TimeOfDay? reminderTime;
final NoteSortType? noteSortType;

const UserConfigModel({
required this.userId,
Expand All @@ -29,6 +52,7 @@ class UserConfigModel extends Equatable {
this.isAutoSaveEnabled,
this.isDailyReminderEnabled,
this.reminderTime,
this.noteSortType,
});

@override
Expand All @@ -43,7 +67,8 @@ class UserConfigModel extends Equatable {
isFingerPrintLoginEnabled,
isAutoSaveEnabled,
isDailyReminderEnabled,
reminderTime
reminderTime,
noteSortType,
];

static TimeOfDay? getTimeOfDayFromTimeString(String? timeString) {
Expand Down Expand Up @@ -98,6 +123,11 @@ class UserConfigModel extends Equatable {
jsonMap[UserConfigConstants.isDailyReminderEnabled],
reminderTime:
getTimeOfDayFromTimeString(jsonMap[UserConfigConstants.reminderTime]),
noteSortType: jsonMap[UserConfigConstants.noteSortType] != null
? NoteSortType.fromStringValue(
jsonMap[UserConfigConstants.noteSortType])
: null,
// noteSortType:
);
}

Expand All @@ -115,7 +145,8 @@ class UserConfigModel extends Equatable {
UserConfigConstants.isFingerPrintLoginEnabled: isFingerPrintLoginEnabled,
UserConfigConstants.isAutoSaveEnabled: isAutoSaveEnabled,
UserConfigConstants.isDailyReminderEnabled: isDailyReminderEnabled,
UserConfigConstants.reminderTime: getTimeOfDayToString(reminderTime)
UserConfigConstants.reminderTime: getTimeOfDayToString(reminderTime),
UserConfigConstants.noteSortType: noteSortType?.text,
};
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:dairy_app/features/auth/core/constants.dart';
import 'package:dairy_app/features/auth/data/models/user_config_model.dart';
import 'package:dairy_app/features/auth/presentation/bloc/user_config/user_config_cubit.dart';
import 'package:dairy_app/features/notes/domain/entities/notes.dart';
import 'package:dairy_app/features/notes/domain/repositories/notes_repository.dart';
import 'package:dairy_app/features/notes/presentation/bloc/notes/notes_bloc.dart';
Expand All @@ -12,16 +15,18 @@ part 'notes_fetch_state.dart';
class NotesFetchCubit extends Cubit<NotesFetchState> {
final INotesRepository notesRepository;
final NotesBloc notesBloc;
final UserConfigCubit userConfigCubit;
late StreamSubscription notesSubscription;

final NoteSyncCubit noteSyncCubit;
late StreamSubscription noteSyncSubscrption;

NotesFetchCubit(
{required this.notesRepository,
required this.notesBloc,
required this.noteSyncCubit})
: super(const NotesFetchDummyState()) {
NotesFetchCubit({
required this.notesRepository,
required this.notesBloc,
required this.noteSyncCubit,
required this.userConfigCubit,
}) : super(const NotesFetchDummyState()) {
notesSubscription = notesBloc.stream.listen((state) {
if (state is NoteSavedSuccesfully) {
fetchNotes();
Expand All @@ -41,6 +46,36 @@ class NotesFetchCubit extends Cubit<NotesFetchState> {
});
}

Future<void> setNoteSortType(NoteSortType noteSortType) async {
await userConfigCubit.setUserConfig(
UserConfigConstants.noteSortType, noteSortType.text);

sortNotes(noteSortType);
}

void sortNotes(NoteSortType noteSortType) {
// Create a new list for sorting
List<NotePreview> notePreviewList = List.from(state.notePreviewList);

// Sort the notePreviewList based on the selected sort type
switch (noteSortType) {
case NoteSortType.sortByLatestFirst:
notePreviewList.sort((a, b) => b.createdAt.compareTo(a.createdAt));
break;
case NoteSortType.sortByOldestFirst:
notePreviewList.sort((a, b) => a.createdAt.compareTo(b.createdAt));
break;
case NoteSortType.sortByAtoZ:
notePreviewList.sort(
(a, b) => a.title.toLowerCase().compareTo(b.title.toLowerCase()));
break;
default:
break;
}

emit(NotesSortSuccessful(notePreviewList: notePreviewList));
}

void fetchNotes(
{String? searchText, DateTime? startDate, DateTime? endDate}) async {
emit(const NotesFetchLoadingState());
Expand All @@ -53,7 +88,15 @@ class NotesFetchCubit extends Cubit<NotesFetchState> {
result.fold((error) {
emit(const NotesFetchFailed());
}, (data) {
// get the preferred note sort type
final preferredNoteSortType =
userConfigCubit.state.userConfigModel?.noteSortType;

emit(NotesFetchSuccessful(notePreviewList: data));

if (preferredNoteSortType != null) {
sortNotes(preferredNoteSortType);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ class NotesFetchSuccessful extends NotesFetchState {
const NotesFetchSuccessful({required List<NotePreview> notePreviewList})
: super(notePreviewList: notePreviewList, safe: true);
}

class NotesSortSuccessful extends NotesFetchState {
const NotesSortSuccessful({required List<NotePreview> notePreviewList})
: super(notePreviewList: notePreviewList, safe: true);
}
4 changes: 4 additions & 0 deletions lib/generated/intl/messages_all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'messages_ar.dart' as messages_ar;
import 'messages_de.dart' as messages_de;
import 'messages_en.dart' as messages_en;
import 'messages_fi.dart' as messages_fi;
import 'messages_gu.dart' as messages_gu;
import 'messages_he.dart' as messages_he;
import 'messages_hi.dart' as messages_hi;
import 'messages_kn.dart' as messages_kn;
Expand All @@ -33,6 +34,7 @@ Map<String, LibraryLoader> _deferredLibraries = {
'de': () => new SynchronousFuture(null),
'en': () => new SynchronousFuture(null),
'fi': () => new SynchronousFuture(null),
'gu': () => new SynchronousFuture(null),
'he': () => new SynchronousFuture(null),
'hi': () => new SynchronousFuture(null),
'kn': () => new SynchronousFuture(null),
Expand All @@ -51,6 +53,8 @@ MessageLookupByLibrary? _findExact(String localeName) {
return messages_en.messages;
case 'fi':
return messages_fi.messages;
case 'gu':
return messages_gu.messages;
case 'he':
return messages_he.messages;
case 'hi':
Expand Down
5 changes: 5 additions & 0 deletions lib/generated/intl/messages_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ class MessageLookup extends MessageLookupByLibrary {
"signIn": MessageLookupByLibrary.simpleMessage("Sign In"),
"signUp": MessageLookupByLibrary.simpleMessage("Sign Up"),
"signedInAs": MessageLookupByLibrary.simpleMessage("Signed in as"),
"sortByAtoZ": MessageLookupByLibrary.simpleMessage("Sort by A-Z"),
"sortByLatestFirst":
MessageLookupByLibrary.simpleMessage("Sort by Latest First"),
"sortByOldestFirst":
MessageLookupByLibrary.simpleMessage("Sort by Oldest First"),
"submit": MessageLookupByLibrary.simpleMessage("Submit"),
"syncNow": MessageLookupByLibrary.simpleMessage("Sync now"),
"tapToExpandTitle":
Expand Down
Loading

0 comments on commit 4c222cd

Please sign in to comment.