Skip to content

Commit

Permalink
Merge pull request #38 from andannn/search_feature
Browse files Browse the repository at this point in the history
Search feature
  • Loading branch information
andannn authored Oct 18, 2023
2 parents af56e53 + 753ae55 commit 52f17f3
Show file tree
Hide file tree
Showing 53 changed files with 1,126 additions and 266 deletions.
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ linter:
- lines_longer_than_80_chars
- curly_braces_in_flow_control_structures
- constant_identifier_names
- avoid_dynamic_calls
18 changes: 10 additions & 8 deletions lib/app/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';


/// context of app root.
BuildContext? globalContext;

Expand Down Expand Up @@ -97,7 +96,7 @@ class _AnimeTrackerAppScaffoldState extends State<AnimeTrackerAppScaffold> {
final animeTrackerRouterDelegate = AFRouterDelegate();

var currentNavigation = TopLevelNavigation.discover;
var needShowAppbar = true;
var needHideNavigationBar = false;

@override
void initState() {
Expand All @@ -106,7 +105,7 @@ class _AnimeTrackerAppScaffoldState extends State<AnimeTrackerAppScaffold> {
setState(() {
currentNavigation =
animeTrackerRouterDelegate.currentTopLevelNavigation;
needShowAppbar = animeTrackerRouterDelegate.needShowTopAppBar;
needHideNavigationBar = animeTrackerRouterDelegate.isTopRouteFullScreen;
});
});
}
Expand Down Expand Up @@ -142,11 +141,14 @@ class _AnimeTrackerAppScaffoldState extends State<AnimeTrackerAppScaffold> {
body: Router(
routerDelegate: animeTrackerRouterDelegate,
backButtonDispatcher: RootBackButtonDispatcher()),
bottomNavigationBar: _animeTrackerNavigationBar(
selected: currentNavigation,
onNavigateToDestination: (navigation) async {
animeTrackerRouterDelegate.navigateToTopLevelPage(navigation);
}),
bottomNavigationBar: needHideNavigationBar
? const SizedBox()
: _animeTrackerNavigationBar(
selected: currentNavigation,
onNavigateToDestination: (navigation) async {
animeTrackerRouterDelegate.navigateToTopLevelPage(navigation);
},
),
),
);
}
Expand Down
35 changes: 22 additions & 13 deletions lib/app/navigation/ani_flow_route_path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import 'package:anime_tracker/feature/anime_track/anime_track.dart';
import 'package:anime_tracker/feature/character_page/character_page.dart';
import 'package:anime_tracker/feature/detail_anime/detail_anime.dart';
import 'package:anime_tracker/feature/discover/discover.dart';
import 'package:anime_tracker/feature/forum/profile.dart';
import 'package:anime_tracker/feature/profile/profile.dart';
import 'package:anime_tracker/feature/staff_page/staff_page.dart';
import 'package:flutter/material.dart';

sealed class AniFlowRoutePath {
const AniFlowRoutePath();
const AniFlowRoutePath({this.isFullScreen = false});

final bool isFullScreen;
}

abstract class TopLevelRoutePath extends AniFlowRoutePath {
Expand All @@ -32,47 +35,51 @@ abstract class TopLevelRoutePath extends AniFlowRoutePath {
}

class DiscoverRoutePath extends TopLevelRoutePath {
DiscoverRoutePath() : super(TopLevelNavigation.discover);
const DiscoverRoutePath() : super(TopLevelNavigation.discover);
}

class TrackRoutePath extends TopLevelRoutePath {
TrackRoutePath() : super(TopLevelNavigation.track);
const TrackRoutePath() : super(TopLevelNavigation.track);
}

class SearchRoutePath extends TopLevelRoutePath {
SearchRoutePath() : super(TopLevelNavigation.search);
class ForumRoutePath extends TopLevelRoutePath {
const ForumRoutePath() : super(TopLevelNavigation.forum);
}

class ProfileRoutePath extends TopLevelRoutePath {
ProfileRoutePath() : super(TopLevelNavigation.profile);
const ProfileRoutePath() : super(TopLevelNavigation.profile);
}

class SearchRoutePath extends AniFlowRoutePath {
const SearchRoutePath() : super(isFullScreen: true);
}

class AnimeListRoutePath extends AniFlowRoutePath {
AnimeListRoutePath(this.category);
const AnimeListRoutePath(this.category) : super(isFullScreen: true);

final AnimeCategory category;
}

class CharacterListRoutePath extends AniFlowRoutePath {
CharacterListRoutePath(this.animeId);
const CharacterListRoutePath(this.animeId) : super(isFullScreen: true);

final String animeId;
}

class StaffListRoutePath extends AniFlowRoutePath {
StaffListRoutePath(this.animeId);
const StaffListRoutePath(this.animeId) : super(isFullScreen: true);

final String animeId;
}

class DetailAnimeRoutePath extends AniFlowRoutePath {
DetailAnimeRoutePath(this.animeId);
const DetailAnimeRoutePath(this.animeId) : super(isFullScreen: true);

final String animeId;
}

class AiringScheduleRoutePath extends AniFlowRoutePath {
const AiringScheduleRoutePath();
const AiringScheduleRoutePath() : super(isFullScreen: true);
}

extension AniFlowRoutePathEx on AniFlowRoutePath {
Expand Down Expand Up @@ -102,12 +109,14 @@ extension AniFlowRoutePathEx on AniFlowRoutePath {
);
case TrackRoutePath(topLevel: final _):
return const AnimeTrackPage(key: ValueKey('AnimeTrackPage'));
case SearchRoutePath(topLevel: final _):
return const AnimeSearchPage(key: ValueKey('AnimeSearchPage'));
case ForumRoutePath(topLevel: final _):
return const ForumPage(key: ValueKey('ForumPage'));
case ProfileRoutePath(topLevel: final _):
return const ProfilePage(key: ValueKey('ProfilePage'));
case AiringScheduleRoutePath():
return const AiringSchedule(key: ValueKey('AiringSchedule'));
case SearchRoutePath():
return const SearchPage(key: ValueKey('SearchPage'));
default:
return const MaterialPage(child: SizedBox());
}
Expand Down
14 changes: 10 additions & 4 deletions lib/app/navigation/ani_flow_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class AFRouterDelegate extends RouterDelegate<AniFlowRoutePath>

RouteObserver routeObserver = RouteObserver();

List<AniFlowRoutePath> _backStack = [DiscoverRoutePath()];
List<AniFlowRoutePath> _backStack = [const DiscoverRoutePath()];

/// get current path.
AniFlowRoutePath get currentPath => _backStack.last;
Expand All @@ -25,7 +25,7 @@ class AFRouterDelegate extends RouterDelegate<AniFlowRoutePath>
.last
.topLevel;

bool get needShowTopAppBar => _backStack.last is TopLevelRoutePath;
bool get isTopRouteFullScreen => _backStack.last.isFullScreen;

static AFRouterDelegate of(context) =>
Router
Expand Down Expand Up @@ -69,9 +69,9 @@ class AFRouterDelegate extends RouterDelegate<AniFlowRoutePath>

void navigateToTopLevelPage(TopLevelNavigation navigation) {
if (navigation == TopLevelNavigation.discover) {
_backStack = [DiscoverRoutePath()];
_backStack = [const DiscoverRoutePath()];
} else {
_backStack = [DiscoverRoutePath(), navigation.toRoutePath()];
_backStack = [const DiscoverRoutePath(), navigation.toRoutePath()];
}

notifyListeners();
Expand Down Expand Up @@ -106,4 +106,10 @@ class AFRouterDelegate extends RouterDelegate<AniFlowRoutePath>

notifyListeners();
}

void navigateToSearch() {
_backStack += [const SearchRoutePath()];

notifyListeners();
}
}
20 changes: 10 additions & 10 deletions lib/app/navigation/top_level_navigation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ enum TopLevelNavigation {
unSelectedIcon: Icons.collections_bookmark_outlined,
iconTextId: 'Track',
),
search(
selectedIcon: Icons.search,
unSelectedIcon: Icons.search,
iconTextId: 'Search',
forum(
selectedIcon: Icons.forum,
unSelectedIcon: Icons.forum_outlined,
iconTextId: 'Forum',
),
profile(
selectedIcon: Icons.person,
unSelectedIcon: Icons.person_outline,
iconTextId: 'profile',
iconTextId: 'Profile',
);

const TopLevelNavigation({
Expand All @@ -46,13 +46,13 @@ extension TopLevelNavigationEx on TopLevelNavigation {
AniFlowRoutePath toRoutePath() {
switch (this) {
case TopLevelNavigation.discover:
return DiscoverRoutePath();
return const DiscoverRoutePath();
case TopLevelNavigation.track:
return TrackRoutePath();
case TopLevelNavigation.search:
return SearchRoutePath();
return const TrackRoutePath();
case TopLevelNavigation.forum:
return const ForumRoutePath();
case TopLevelNavigation.profile:
return ProfileRoutePath();
return const ProfileRoutePath();
}
}
}
22 changes: 22 additions & 0 deletions lib/core/common/util/load_page_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,26 @@ mixin LoadPageUtil {
return LoadError(e);
}
}

static Future<LoadResult<List<Model>>> loadPageWithoutDBCache<Dto, Model>({
required page,
required perPage,
required Future<List<Dto>> Function(int page, int perPage) onGetNetworkRes,
required Future<void> Function(List<Dto> dto) onInsertEntityToDB,
required Model Function(Dto dto) mapDtoToModel,
}) async {
try {
/// get data from network datasource.
final networkRes = await onGetNetworkRes(page, perPage);

/// insert network resource to DB.
await onInsertEntityToDB(networkRes);

/// load success, return result.
return LoadSuccess(
data: networkRes.map((e) => mapDtoToModel(e)).toList());
} on DioException catch (e) {
return LoadError(e);
}
}
}
6 changes: 3 additions & 3 deletions lib/core/data/ani_list_repository.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'package:anime_tracker/core/common/util/global_static_constants.dart';
import 'package:anime_tracker/core/data/load_result.dart';
import 'package:anime_tracker/core/data/model/anime_list_item_model.dart';
import 'package:anime_tracker/core/database/anime_dao.dart';
import 'package:anime_tracker/core/database/anime_database.dart';
import 'package:anime_tracker/core/database/anime_track_list_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_track_list_dao.dart';
import 'package:anime_tracker/core/database/dao/user_data_dao.dart';
import 'package:anime_tracker/core/database/model/anime_entity.dart';
import 'package:anime_tracker/core/database/model/anime_track_item_entity.dart';
import 'package:anime_tracker/core/database/user_data_dao.dart';
import 'package:anime_tracker/core/network/ani_list_data_source.dart';
import 'package:anime_tracker/core/network/api/ani_save_media_list_mution_graphql.dart';
import 'package:anime_tracker/core/network/api/user_anime_list_query_graphql.dart';
Expand Down
4 changes: 2 additions & 2 deletions lib/core/data/auth_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import 'dart:async';
import 'package:anime_tracker/core/channel/auth_event_channel.dart';
import 'package:anime_tracker/core/data/model/user_data_model.dart';
import 'package:anime_tracker/core/database/anime_database.dart';
import 'package:anime_tracker/core/database/anime_track_list_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_track_list_dao.dart';
import 'package:anime_tracker/core/database/dao/user_data_dao.dart';
import 'package:anime_tracker/core/database/model/user_data_entity.dart';
import 'package:anime_tracker/core/database/user_data_dao.dart';
import 'package:anime_tracker/core/network/auth_data_source.dart';
import 'package:anime_tracker/core/shared_preference/user_data.dart';
import 'package:url_launcher/url_launcher.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/core/data/media_information_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import 'package:anime_tracker/core/data/model/airing_schedule_model.dart';
import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:anime_tracker/core/data/model/character_and_voice_actor_model.dart';
import 'package:anime_tracker/core/data/model/staff_and_role_model.dart';
import 'package:anime_tracker/core/database/anime_dao.dart';
import 'package:anime_tracker/core/database/anime_database.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/database/model/airing_schedules_entity.dart';
import 'package:anime_tracker/core/database/model/anime_entity.dart';
import 'package:anime_tracker/core/database/model/character_entity.dart';
Expand Down
6 changes: 6 additions & 0 deletions lib/core/data/model/anime_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:anime_tracker/core/data/model/staff_and_role_model.dart';
import 'package:anime_tracker/core/data/model/trailter_model.dart';
import 'package:anime_tracker/core/database/model/anime_entity.dart';
import 'package:anime_tracker/core/database/model/relations/anime_and_detail_info.dart';
import 'package:anime_tracker/core/network/model/anime_dto.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'anime_model.freezed.dart';
Expand Down Expand Up @@ -101,4 +102,9 @@ class AnimeModel with _$AnimeModel {
.toList(),
);
}

static AnimeModel fromDto(AnimeDto dto) {
final entity = AnimeEntity.fromNetworkModel(dto);
return AnimeModel.fromDatabaseModel(entity);
}
}
39 changes: 39 additions & 0 deletions lib/core/data/search_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'dart:async';

import 'package:anime_tracker/core/common/util/load_page_util.dart';
import 'package:anime_tracker/core/data/load_result.dart';
import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:anime_tracker/core/database/anime_database.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/database/model/anime_entity.dart';
import 'package:anime_tracker/core/network/ani_list_data_source.dart';
import 'package:anime_tracker/core/network/model/anime_dto.dart';

abstract class SearchRepository {
Future<LoadResult<List<AnimeModel>>> loadMediaSearchResultByPage(
{required int page, required int perPage, required String search});
}

class SearchRepositoryImpl implements SearchRepository {
final AniListDataSource dataSource = AniListDataSource();
final AnimeListDao dao = AnimeDatabase().getAnimeDao();

@override
Future<LoadResult<List<AnimeModel>>> loadMediaSearchResultByPage(
{required int page, required int perPage, required String search}) {
return LoadPageUtil.loadPageWithoutDBCache<AnimeDto, AnimeModel>(
page: page,
perPage: perPage,
onGetNetworkRes: (int page, int perPage) => dataSource.searchAnimePage(
page: page,
perPage: perPage,
search: search,
),
mapDtoToModel: (AnimeDto dto) => AnimeModel.fromDto(dto),
onInsertEntityToDB: (List<AnimeDto> dto) async {
final entities = dto.map((e) => AnimeEntity.fromNetworkModel(e)).toList();
await dao.upsertAnimeInformation(entities);
},
);
}
}
6 changes: 3 additions & 3 deletions lib/core/database/anime_database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import 'dart:async';

import 'package:anime_tracker/core/database/anime_dao.dart';
import 'package:anime_tracker/core/database/anime_track_list_dao.dart';
import 'package:anime_tracker/core/database/user_data_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_track_list_dao.dart';
import 'package:anime_tracker/core/database/dao/user_data_dao.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// ignore_for_file: lines_longer_than_80_chars
// ignore_for_file: lines_longer_than_80_chars, avoid_dynamic_calls

import 'dart:async';

import 'package:anime_tracker/core/common/util/global_static_constants.dart';
import 'package:anime_tracker/core/common/util/stream_util.dart';
import 'package:anime_tracker/core/data/ani_list_repository.dart';
import 'package:anime_tracker/core/database/anime_dao.dart';
import 'package:anime_tracker/core/database/anime_database.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/database/model/anime_entity.dart';
import 'package:anime_tracker/core/database/model/anime_track_item_entity.dart';
import 'package:anime_tracker/core/database/model/relations/user_anime_list_and_anime.dart';
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/core/database/model/airing_schedules_entity.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:anime_tracker/core/database/anime_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/network/model/airing_schedule_dto.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

Expand Down
2 changes: 1 addition & 1 deletion lib/core/database/model/anime_entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'dart:convert';
import 'package:anime_tracker/core/common/model/anime_season.dart';
import 'package:anime_tracker/core/common/model/anime_source.dart';
import 'package:anime_tracker/core/common/model/anime_status.dart';
import 'package:anime_tracker/core/database/anime_dao.dart';
import 'package:anime_tracker/core/database/dao/anime_dao.dart';
import 'package:anime_tracker/core/network/model/anime_dto.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

Expand Down
Loading

0 comments on commit 52f17f3

Please sign in to comment.