Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -536,4 +536,4 @@
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
}
6 changes: 5 additions & 1 deletion client/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:pr12er/service.dart';
import 'package:pr12er/sort_preference.dart';
import 'package:pr12er/view_models/view_model_videos.dart';
import 'package:provider/provider.dart';

Expand All @@ -18,7 +19,10 @@ void main() => runApp(MultiProvider(providers: [
),
ChangeNotifierProvider<FavoriteVideoViewModel>(
create: (context) => FavoriteVideoViewModel(),
)
),
ChangeNotifierProvider(
create: (context) => SortMode(),
),
], child: const MainApp()));

class MainApp extends StatelessWidget {
Expand Down
47 changes: 28 additions & 19 deletions client/lib/screens/main_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:provider/provider.dart';

import '../protos/pkg/pr12er/messages.pb.dart';
import '../service.dart';
import '../sort_preference.dart';
import '../widgets/components/custom_app_bar.dart';
import '../widgets/components/custom_bottom_navigation_bar.dart';
import '../widgets/main/main_screen_favorite_view.dart';
Expand Down Expand Up @@ -37,25 +38,33 @@ class _MainScreenState extends State<MainScreen> {
.where((video) => video.hasTitle() && video.hasLink())
.toList();

return Scaffold(
appBar: CustomAppBar(
videoSearchDelegate: videoSearchDelegate,
context: context,
title: appName,
),
body: IndexedStack(
index: _selectedBottomNavIndex,
children: [
MainScreenListView(cleanList: cleanList),
MainScreenFavoriteView(cleanList: cleanList)
],
),
bottomNavigationBar: CustomBottomNavigationBar(
selectedBottomNavIndex: _selectedBottomNavIndex,
onTap: (index) => setState(() {
_selectedBottomNavIndex = index;
videoSearchDelegate.showOnlyBookmarkItems = index == 1;
})));
return Consumer<SortMode>(
builder: (context, sort, _child) => Scaffold(
appBar: CustomAppBar(
videoSearchDelegate: videoSearchDelegate,
context: context,
title: appName,
),
body: IndexedStack(
index: _selectedBottomNavIndex,
children: [
MainScreenListView(
cleanList: sort.isDescOrder
? cleanList
: List.from(cleanList.reversed)),
MainScreenFavoriteView(
cleanList: sort.isDescOrder
? cleanList
: List.from(cleanList.reversed))
],
),
bottomNavigationBar: CustomBottomNavigationBar(
selectedBottomNavIndex: _selectedBottomNavIndex,
onTap: (index) => setState(() {
_selectedBottomNavIndex = index;
videoSearchDelegate.showOnlyBookmarkItems =
index == 1;
}))));
});
}
}
43 changes: 43 additions & 0 deletions client/lib/sort_preference.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

const _sharedPreferenceSortModeKey = "isDescOrder";

class SortMode extends ChangeNotifier {
bool _isDescOrder = false;

bool get isDescOrder {
return _isDescOrder;
}

/// sharedPreferences is only visible for testing.
/// It is used to test isDarkMode is being loaded from SharedPreferences.
@visibleForTesting
Future<SharedPreferences> get sharedPreferences =>
SharedPreferences.getInstance();

void toggleMode() {
_isDescOrder = !_isDescOrder;
SharedPreferences.getInstance().then(
(pref) => pref.setBool(_sharedPreferenceSortModeKey, _isDescOrder));
notifyListeners();
}

// This type should not be a widget(e.g. Icon) because of mockito support...
IconData get icon =>
_isDescOrder ? Icons.vertical_align_top : Icons.vertical_align_bottom;

// This type should not be a widget(e.g. Text) because of mockito support...
String get text => _isDescOrder ? "오름차순으로" : "내림차순으로";

SortMode() {
SharedPreferences.getInstance().then((pref) {
final isDescOrder = pref.getBool(_sharedPreferenceSortModeKey);
if (isDescOrder != null) {
_isDescOrder = isDescOrder;
notifyListeners();
}
});
}
}
13 changes: 12 additions & 1 deletion client/lib/widgets/components/custom_app_bar.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:pr12er/custom_theme.dart';
import 'package:pr12er/sort_preference.dart';
import 'package:pr12er/widgets/main/report.dart';
import 'package:pr12er/widgets/main/video_search_delegate.dart';
import 'package:provider/provider.dart';

enum VertMenu { themeMode, issueReport }
enum VertMenu { themeMode, sortMode, issueReport }

class CustomAppBar extends AppBar {
CustomAppBar({
Expand Down Expand Up @@ -36,6 +37,13 @@ class CustomAppBar extends AppBar {
leading: Icon(context.read<CustomTheme>().icon),
title: Text(context.read<CustomTheme>().text))),
const PopupMenuDivider(height: 5),
PopupMenuItem<VertMenu>(
key: const ValueKey("icon-sort-toggle-button"),
value: VertMenu.sortMode,
child: ListTile(
leading: Icon(context.read<SortMode>().icon),
title: Text(context.read<SortMode>().text))),
const PopupMenuDivider(height: 5),
const PopupMenuItem<VertMenu>(
key: ValueKey("popup-menu-item-issue-report"),
value: VertMenu.issueReport,
Expand All @@ -50,6 +58,9 @@ class CustomAppBar extends AppBar {
case VertMenu.themeMode:
context.read<CustomTheme>().toggleMode();
break;
case VertMenu.sortMode:
context.read<SortMode>().toggleMode();
break;
case VertMenu.issueReport:
showMaterialModalBottomSheet(
context: context,
Expand Down
4 changes: 4 additions & 0 deletions client/test/screens/main_screen_with_mocks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:pr12er/custom_theme.dart';
import 'package:pr12er/protos/pkg/pr12er/messages.pb.dart';
import 'package:pr12er/screens/main_screen.dart';
import 'package:pr12er/service.dart';
import 'package:pr12er/sort_preference.dart';
import 'package:pr12er/view_models/view_model_videos.dart';
import 'package:provider/provider.dart';

Expand Down Expand Up @@ -112,6 +113,9 @@ MultiProvider wrapWithProviders(
ChangeNotifierProvider<CustomTheme>(create: (context) => mockCustomTheme),
ChangeNotifierProvider<FavoriteVideoViewModel>(
create: (context) => mockFavoriteVideoViewModel),
ChangeNotifierProvider<SortMode>(
create: (context) => SortMode(),
)
],
builder: (context, child) => MaterialApp(home: MainScreen()),
);
Expand Down