Skip to content

Commit

Permalink
Merge pull request #34 from andannn/staff_and_charactor_page
Browse files Browse the repository at this point in the history
Staff and charactor page
  • Loading branch information
andannn authored Oct 16, 2023
2 parents 13a57fe + 5c4859b commit 5bb8063
Show file tree
Hide file tree
Showing 73 changed files with 1,021 additions and 751 deletions.
4 changes: 4 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,7 @@ linter:
- package_names
- always_use_package_imports
- unawaited_futures
- directives_ordering
- lines_longer_than_80_chars
- curly_braces_in_flow_control_structures
- constant_identifier_names
16 changes: 8 additions & 8 deletions lib/app/app.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import 'package:anime_tracker/core/design_system/theme/colors.dart';
import 'package:anime_tracker/core/data/media_information_repository.dart';
import 'package:anime_tracker/core/data/auth_repository.dart';
import 'package:anime_tracker/app/local/ani_flow_localizations_delegate.dart';
import 'package:anime_tracker/app/navigation/ani_flow_router.dart';
import 'package:anime_tracker/app/navigation/top_level_navigation.dart';
import 'package:anime_tracker/core/data/ani_list_repository.dart';
import 'package:anime_tracker/core/data/auth_repository.dart';
import 'package:anime_tracker/core/data/media_information_repository.dart';
import 'package:anime_tracker/core/data/user_data_repository.dart';
import 'package:anime_tracker/core/design_system/theme/colors.dart';
import 'package:anime_tracker/feature/anime_track/bloc/track_bloc.dart';
import 'package:anime_tracker/feature/discover/bloc/discover_bloc.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:anime_tracker/core/data/user_data_repository.dart';
import 'package:anime_tracker/app/local/ani_flow_localizations_delegate.dart';
import 'package:anime_tracker/app/navigation/ani_flow_router.dart';
import 'package:anime_tracker/app/navigation/top_level_navigation.dart';


/// context of app root.
Expand Down Expand Up @@ -94,7 +94,7 @@ class AnimeTrackerAppScaffold extends StatefulWidget {
}

class _AnimeTrackerAppScaffoldState extends State<AnimeTrackerAppScaffold> {
final animeTrackerRouterDelegate = AnimeTrackerRouterDelegate();
final animeTrackerRouterDelegate = AFRouterDelegate();

var currentNavigation = TopLevelNavigation.discover;
var needShowAppbar = true;
Expand Down
5 changes: 2 additions & 3 deletions lib/app/local/ani_flow_localizations_delegate.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

import 'package:anime_tracker/app/local/ani_flow_localizations.dart';
import 'package:flutter/cupertino.dart';

class AnimeTrackerLocalizationsDelegate extends LocalizationsDelegate<AFLocalizations> {
class AnimeTrackerLocalizationsDelegate
extends LocalizationsDelegate<AFLocalizations> {
@override
bool isSupported(Locale locale) {
return ['en', 'Jpan', 'ja', 'zh'].contains(locale.languageCode);
Expand All @@ -25,5 +25,4 @@ class AnimeTrackerLocalizationsDelegate extends LocalizationsDelegate<AFLocaliza
bool shouldReload(covariant LocalizationsDelegate<AFLocalizations> old) {
return false;
}

}
4 changes: 2 additions & 2 deletions lib/app/local/util/anime_model_extension.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:anime_tracker/app/local/ani_flow_localizations.dart';
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/common/model/character_role.dart';
import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:anime_tracker/core/common/model/anime_source.dart';
import 'package:anime_tracker/core/common/util/time_util.dart';
import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:flutter/material.dart';

extension AnimeSourceEx on AnimeSource {
Expand Down
14 changes: 13 additions & 1 deletion lib/app/navigation/ani_flow_route_path.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:anime_tracker/app/navigation/top_level_navigation.dart';
import 'package:anime_tracker/core/common/model/anime_category.dart';
import 'package:anime_tracker/feature/airing_schedule/airing_schedule.dart';
import 'package:anime_tracker/feature/anime_list/anime_list.dart';
import 'package:anime_tracker/feature/anime_page/anime_page.dart';
import 'package:anime_tracker/feature/anime_search/anime_search.dart';
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/profile/profile.dart';
Expand Down Expand Up @@ -51,6 +52,12 @@ class AnimeListRoutePath extends AniFlowRoutePath {
final AnimeCategory category;
}

class CharacterListRoutePath extends AniFlowRoutePath {
CharacterListRoutePath(this.animeId);

final String animeId;
}

class DetailAnimeRoutePath extends AniFlowRoutePath {
DetailAnimeRoutePath(this.animeId);

Expand All @@ -71,6 +78,11 @@ extension AniFlowRoutePathEx on AniFlowRoutePath {
key: ValueKey('AnimeListPage_$category'),
category: category,
);
case CharacterListRoutePath(animeId: final animeId):
return CharacterListPage(
key: ValueKey('CharacterListPage_$animeId'),
animeId: animeId,
);
case DetailAnimeRoutePath(animeId: final animeId):
return DetailAnimePage(
key: ValueKey('DetailAnimeRoute_$animeId'),
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
@@ -1,9 +1,9 @@
import 'package:anime_tracker/app/navigation/ani_flow_route_path.dart';
import 'package:anime_tracker/app/navigation/top_level_navigation.dart';
import 'package:anime_tracker/core/common/model/anime_category.dart';
import 'package:flutter/material.dart';
import 'package:anime_tracker/app/navigation/ani_flow_route_path.dart';

class AnimeTrackerRouterDelegate extends RouterDelegate<AniFlowRoutePath>
class AFRouterDelegate extends RouterDelegate<AniFlowRoutePath>
with ChangeNotifier {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey();

Expand All @@ -27,10 +27,10 @@ class AnimeTrackerRouterDelegate extends RouterDelegate<AniFlowRoutePath>

bool get needShowTopAppBar => _backStack.last is TopLevelRoutePath;

static AnimeTrackerRouterDelegate of(context) =>
static AFRouterDelegate of(context) =>
Router
.of(context)
.routerDelegate as AnimeTrackerRouterDelegate;
.routerDelegate as AFRouterDelegate;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -83,6 +83,12 @@ class AnimeTrackerRouterDelegate extends RouterDelegate<AniFlowRoutePath>
notifyListeners();
}

void navigateToCharacterList(String animeId) {
_backStack += [CharacterListRoutePath(animeId)];

notifyListeners();
}

void navigateToDetailAnime(String animeId) {
_backStack += [DetailAnimeRoutePath(animeId)];

Expand Down
3 changes: 1 addition & 2 deletions lib/app/navigation/top_level_navigation.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';

import 'package:anime_tracker/app/navigation/ani_flow_route_path.dart';
import 'package:flutter/material.dart';

enum TopLevelNavigation {
discover(
Expand Down
4 changes: 3 additions & 1 deletion lib/core/channel/auth_event_channel.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/services.dart';

import 'package:anime_tracker/core/common/util/logger.dart';
import 'package:flutter/services.dart';

class AuthResult {
AuthResult({required this.token, required this.expiresInTime});
Expand Down Expand Up @@ -38,6 +39,7 @@ class AuthEventChannel {
}

logger.d('login success and token will be expired in'
// ignore: lines_longer_than_80_chars
' ${DateTime.fromMillisecondsSinceEpoch(DateTime.now().millisecondsSinceEpoch + expiresInTime)}');
completer.complete(
AuthResult(token: token, expiresInTime: expiresInTime),
Expand Down
3 changes: 2 additions & 1 deletion lib/core/common/util/load_page_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ mixin LoadPageUtil {
case Append(page: int page, perPage: int perPage):
final dbResult = await onGetEntityFromDB(page, perPage);
if (dbResult.length < perPage) {
/// the data in database is not enough for one page. try to get data from network.
/// the data in database is not enough for one page.
/// try to get data from network.
final networkRes = await onGetNetworkRes(page, perPage);

/// insert the network data to db.
Expand Down
3 changes: 2 additions & 1 deletion lib/core/common/util/time_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ mixin TimeUtil {
return result.firstOrNull;
}

/// Get range of millisecondsSinceEpoch, which is [daysAgo] from today and [daysAfter] after today.
/// Get range of millisecondsSinceEpoch, which is [daysAgo] from today
/// and [daysAfter] after today.
/// For example:
/// current time is: 2023-10-11 15:10:26.818764
/// return rage is: (2023-10-05 00:00:00.000, 2023-10-17 23:59:59.999)
Expand Down
5 changes: 3 additions & 2 deletions lib/core/data/ani_list_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ 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/model/anime_entity.dart';
import 'package:anime_tracker/core/database/model/anime_track_item_entity.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/network/ani_list_data_source.dart';
import 'package:anime_tracker/core/network/api/ani_save_media_list_mution_graphql.dart';
Expand Down Expand Up @@ -160,7 +160,8 @@ class AnimeTrackListRepositoryImpl extends AniListRepository {

if (entity != null) {
/// the tracking anime is already cached in database.
/// change the local database and notify the to ui without waiting network result.
/// change the local database and notify the to ui without waiting
/// network result.
final updatedEntity = entity.copyWith(
status: status,
progress: progress ?? entity.progress,
Expand Down
4 changes: 2 additions & 2 deletions lib/core/data/auth_repository.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
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/model/user_data_entity.dart';
import 'package:anime_tracker/core/database/anime_track_list_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';
import 'package:anime_tracker/core/data/model/user_data_model.dart';

const String _clientId = '14409';

Expand Down
84 changes: 50 additions & 34 deletions lib/core/data/media_information_repository.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import 'package:anime_tracker/core/common/model/anime_category.dart';
import 'package:anime_tracker/core/common/util/load_page_util.dart';
import 'package:anime_tracker/core/common/util/time_util.dart';
import 'package:anime_tracker/core/data/load_result.dart';
import 'package:anime_tracker/core/data/model/airing_schedule_and_anime_model.dart';
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/database/anime_dao.dart';
import 'package:anime_tracker/core/database/anime_database.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';
import 'package:anime_tracker/core/database/model/media_external_link_entity.dart';
import 'package:anime_tracker/core/database/model/relations/anime_and_detail_info.dart';
import 'package:anime_tracker/core/database/model/staff_entity.dart';
import 'package:anime_tracker/core/network/ani_list_data_source.dart';
import 'package:anime_tracker/core/network/api/airing_schedules_query_graphql.dart.dart';
import 'package:anime_tracker/core/network/model/character_edge.dart';
import 'package:anime_tracker/core/network/api/ani_list_query_graphql.dart';
import 'package:anime_tracker/core/network/model/anime_dto.dart';
import 'package:anime_tracker/core/network/model/character_edge.dart';
import 'package:anime_tracker/core/network/model/media_external_links_dto.dart';
import 'package:anime_tracker/core/network/model/staff_edge.dart';
import 'package:anime_tracker/core/common/util/time_util.dart';
import 'package:dio/dio.dart';

import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:anime_tracker/core/database/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/api/ani_list_query_graphql.dart';
import 'package:anime_tracker/core/shared_preference/user_data.dart';

import 'package:anime_tracker/core/network/util/http_status_util.dart';
import 'package:anime_tracker/core/shared_preference/user_data.dart';
import 'package:dio/dio.dart';
import 'package:sqflite/sqflite.dart';

/// repository for get anime list.
Expand All @@ -33,6 +33,12 @@ abstract class MediaInformationRepository {
required LoadType loadType,
});

Future<LoadResult<List<CharacterAndVoiceActorModel>>>
loadCharacterPageByAnimeId({
required String animeId,
required LoadType loadType,
});

Stream<AnimeModel> getDetailAnimeInfoStream(String id);

Future<LoadResult<void>> startFetchDetailAnimeInfo(String id);
Expand Down Expand Up @@ -77,6 +83,32 @@ class MediaInformationRepositoryImpl extends MediaInformationRepository {
);
}

@override
Future<LoadResult<List<CharacterAndVoiceActorModel>>>
loadCharacterPageByAnimeId(
{required String animeId, required LoadType loadType}) async {
return LoadPageUtil.loadPage<CharacterEdge, CharacterAndVoiceActor,
CharacterAndVoiceActorModel>(
type: loadType,
onGetNetworkRes: (page, perPage) => aniListDataSource.getCharacterPage(
animeId: int.parse(animeId), page: page, perPage: perPage),
onClearDbCache: () async {},
onInsertEntityToDB: (entities) => animeDao.insertCharacterVoiceActors(
animeId: int.parse(animeId), entities: entities),
onGetEntityFromDB: (page, perPage) => animeDao.getCharacterOfAnimeByPage(
animeId.toString(),
page: page,
perPage: perPage,
),
mapDtoToEntity: (dto) => CharacterAndVoiceActor(
characterEntity: CharacterEntity.fromNetworkModel(dto),
voiceActorEntity: StaffEntity.fromVoiceActorDto(dto),
),
mapEntityToModel: (entity) =>
CharacterAndVoiceActorModel.fromDatabaseEntity(entity),
);
}

@override
Stream<AnimeModel> getDetailAnimeInfoStream(String id) {
return animeDao.getDetailAnimeInfoStream(id).map(
Expand All @@ -101,33 +133,17 @@ class MediaInformationRepositoryImpl extends MediaInformationRepository {
networkResult.characters?.edges ?? [];
if (characters.isNotEmpty) {
/// inset character entities to db.
final List<CharacterEntity> characterEntities = characters
final List<CharacterAndVoiceActor> characterAndVoiceActors = characters
.map(
(e) => CharacterEntity.fromNetworkModel(e),
(e) => CharacterAndVoiceActor(
characterEntity: CharacterEntity.fromNetworkModel(e),
voiceActorEntity: StaffEntity.fromVoiceActorDto(e),
),
)
.toList();
await animeDao.upsertCharacterInfo(characterEntities);

/// inset voice actor entities to db.
final List<StaffEntity> voiceActorEntities = characters
.map(
(e) => StaffEntity.fromVoiceActorDto(e),
)
.whereType<StaffEntity>()
.toList();
await animeDao.upsertStaffInfo(voiceActorEntities);

/// Set crossRefs to anime and characters.
await animeDao.upsertAnimeCharacterCrossRef(
crossRefs: characters
.map(
(e) => AnimeCharacterCrossRef(
animeId: id.toString(),
characterId: e.characterNode!.id.toString(),
),
)
.toList(),
);
await animeDao.insertCharacterVoiceActors(
animeId: int.parse(id), entities: characterAndVoiceActors);
}

final List<StaffEdge> staffs = networkResult.staff?.edges ?? [];
Expand Down
6 changes: 3 additions & 3 deletions lib/core/data/model/airing_schedule_and_anime_model.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

import 'package:anime_tracker/core/data/model/airing_schedule_model.dart';
import 'package:anime_tracker/core/data/model/anime_model.dart';

class AiringScheduleAndAnimeModel {
AiringScheduleAndAnimeModel({required this.airingSchedule, required this.animeModel});
AiringScheduleAndAnimeModel(
{required this.airingSchedule, required this.animeModel});

final AiringScheduleModel airingSchedule;
final AnimeModel animeModel;
}
}
2 changes: 1 addition & 1 deletion lib/core/data/model/anime_list_item_model.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:anime_tracker/core/data/ani_list_repository.dart';
import 'package:anime_tracker/core/data/model/anime_model.dart';
import 'package:anime_tracker/core/database/model/relations/user_anime_list_and_anime.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

Expand Down
9 changes: 4 additions & 5 deletions lib/core/data/model/anime_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ 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/data/model/staff_and_role_model.dart';
import 'package:anime_tracker/core/data/model/trailter_model.dart';
import 'package:anime_tracker/core/data/model/media_external_link_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

import 'package:anime_tracker/core/data/model/anime_title_modle.dart';
import 'package:anime_tracker/core/data/model/character_and_voice_actor_model.dart';
import 'package:anime_tracker/core/data/model/media_external_link_model.dart';
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:freezed_annotation/freezed_annotation.dart';

part 'anime_model.freezed.dart';

Expand Down
Loading

0 comments on commit 5bb8063

Please sign in to comment.