Skip to content

Commit

Permalink
feat: add comments for gelbooru
Browse files Browse the repository at this point in the history
  • Loading branch information
khoadng committed Jun 25, 2023
1 parent 75e5acd commit c63ffbd
Show file tree
Hide file tree
Showing 13 changed files with 368 additions and 1 deletion.
11 changes: 11 additions & 0 deletions lib/api/gelbooru/gelbooru_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,15 @@ abstract class GelbooruApi {
@Query('term') String term, {
@CancelRequest() CancelToken? cancelToken,
});

@GET('/index.php')
Future<HttpResponse> getComments(
@Query('api_key') String? apiKey,
@Query('user_id') String? userId,
@Query('page') String page,
@Query('s') String s,
@Query('q') String q,
@Query('post_id') int postId, {
@CancelRequest() CancelToken? cancelToken,
});
}
4 changes: 4 additions & 0 deletions lib/boorus/gelbooru/feats/comments/comments.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export 'gelbooru_comment.dart';
export 'gelbooru_comment_dto.dart';
export 'gelbooru_comment_provider.dart';
export 'gelbooru_comment_repository.dart';
30 changes: 30 additions & 0 deletions lib/boorus/gelbooru/feats/comments/gelbooru_comment.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Package imports:
import 'package:equatable/equatable.dart';

class GelbooruComment extends Equatable {
const GelbooruComment({
required this.id,
required this.postId,
required this.body,
required this.creatorId,
required this.creator,
required this.createdAt,
});

final int id;
final int postId;
final String body;
final int creatorId;
final String creator;
final DateTime createdAt;

@override
List<Object?> get props => [
id,
postId,
body,
creatorId,
createdAt,
creator,
];
}
31 changes: 31 additions & 0 deletions lib/boorus/gelbooru/feats/comments/gelbooru_comment_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Package imports:
import 'package:xml/xml.dart' as xml;

class GelbooruCommentDto {
final String? createdAt;
final String? postId;
final String? body;
final String? creator;
final String? id;
final String? creatorId;

GelbooruCommentDto({
this.createdAt,
this.postId,
this.body,
this.creator,
this.id,
this.creatorId,
});

factory GelbooruCommentDto.fromXml(xml.XmlElement element) {
return GelbooruCommentDto(
createdAt: element.getAttribute('created_at'),
postId: element.getAttribute('post_id'),
body: element.getAttribute('body'),
creator: element.getAttribute('creator'),
id: element.getAttribute('id'),
creatorId: element.getAttribute('creator_id'),
);
}
}
18 changes: 18 additions & 0 deletions lib/boorus/gelbooru/feats/comments/gelbooru_comment_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Package imports:
import 'package:flutter_riverpod/flutter_riverpod.dart';

// Project imports:
import 'package:boorusama/boorus/core/feats/boorus/providers.dart';
import 'package:boorusama/boorus/gelbooru/feats/comments/comments.dart';
import 'package:boorusama/boorus/gelbooru/gelbooru_provider.dart';

final gelbooruCommentRepoProvider = Provider<GelbooruCommentRepository>(
(ref) => GelbooruCommentRepositoryApi(
api: ref.read(gelbooruApiProvider),
booruConfig: ref.read(currentBooruConfigProvider),
),
);

final gelbooruCommentsProvider =
FutureProvider.family<List<GelbooruComment>, int>((ref, postId) =>
ref.read(gelbooruCommentRepoProvider).getComments(postId));
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Dart imports:
import 'dart:async';

// Package imports:
import 'package:intl/intl.dart';
import 'package:xml/xml.dart';

// Project imports:
import 'package:boorusama/api/gelbooru/gelbooru_api.dart';
import 'package:boorusama/boorus/core/feats/boorus/boorus.dart';
import 'package:boorusama/boorus/gelbooru/feats/comments/gelbooru_comment.dart';
import 'package:boorusama/dart.dart';
import 'gelbooru_comment_dto.dart';

abstract interface class GelbooruCommentRepository {
Future<List<GelbooruComment>> getComments(int postId);
}

class GelbooruCommentRepositoryApi implements GelbooruCommentRepository {
GelbooruCommentRepositoryApi({
required this.api,
required this.booruConfig,
});

final GelbooruApi api;
final BooruConfig booruConfig;

@override
Future<List<GelbooruComment>> getComments(int postId) => api
.getComments(
booruConfig.login,
booruConfig.apiKey,
'dapi',
'comment',
'index',
postId,
)
.then(_parseCommentDtos)
.then((value) => value.map(gelboorucommentDtoToGelbooruComment).toList())
.catchError((e) => <GelbooruComment>[]);
}

FutureOr<List<GelbooruCommentDto>> _parseCommentDtos(value) {
final dtos = <GelbooruCommentDto>[];
final xmlDocument = XmlDocument.parse(value.data);
final comments = xmlDocument.findAllElements('comment');
for (final item in comments) {
dtos.add(GelbooruCommentDto.fromXml(item));
}
return dtos;
}

GelbooruComment gelboorucommentDtoToGelbooruComment(GelbooruCommentDto dto) {
return GelbooruComment(
id: int.tryParse(dto.id ?? '') ?? 0,
postId: int.tryParse(dto.postId ?? '') ?? 0,
body: dto.body ?? '',
creator: dto.creator ?? '',
creatorId: int.tryParse(dto.creatorId ?? '') ?? 0,
createdAt: DateFormat('yyyy-MM-dd HH:mm').tryParse(dto.createdAt ?? '') ??
DateTime.now(),
);
}
52 changes: 52 additions & 0 deletions lib/boorus/gelbooru/pages/comments/gelbooru_comment_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Flutter imports:
import 'package:flutter/material.dart';

// Package imports:
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

// Project imports:
import 'package:boorusama/boorus/core/feats/boorus/boorus.dart';
import 'package:boorusama/boorus/core/feats/dtext/html_converter.dart';
import 'package:boorusama/boorus/core/widgets/comment_header.dart';
import 'package:boorusama/boorus/gelbooru/feats/comments/comments.dart';
import 'package:boorusama/flutter.dart';

class GelbooruCommentItem extends ConsumerWidget {
const GelbooruCommentItem({
super.key,
required this.comment,
});

final GelbooruComment comment;

@override
Widget build(BuildContext context, WidgetRef ref) {
final booru = ref.watch(currentBooruProvider);

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CommentHeader(
authorName: comment.creator.isEmpty
? comment.creatorId.toString()
: comment.creator,
authorTitleColor: context.colorScheme.primary,
createdAt: comment.createdAt,
),
const SizedBox(height: 4),
Html(
style: {
'body': Style(
margin: EdgeInsets.zero,
),
},
data: dtext(
comment.body,
booru: booru,
),
)
],
);
}
}
45 changes: 45 additions & 0 deletions lib/boorus/gelbooru/pages/comments/gelbooru_comment_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Flutter imports:
import 'package:flutter/material.dart';

// Package imports:
import 'package:flutter_riverpod/flutter_riverpod.dart';

// Project imports:
import 'package:boorusama/boorus/core/widgets/widgets.dart';
import 'package:boorusama/boorus/gelbooru/feats/comments/comments.dart';
import 'package:boorusama/boorus/gelbooru/pages/comments/gelbooru_comment_item.dart';
import 'package:boorusama/foundation/i18n.dart';

class GelbooruCommentPage extends ConsumerWidget {
const GelbooruCommentPage({
super.key,
required this.postId,
});

final int postId;

@override
Widget build(BuildContext context, WidgetRef ref) {
final comments = ref.watch(gelbooruCommentsProvider(postId));

return Scaffold(
appBar: AppBar(
title: const Text('comment.comments').tr(),
),
body: comments.when(
data: (comments) => comments.isNotEmpty
? ListView.builder(
itemCount: comments.length,
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: GelbooruCommentItem(comment: comments[index]),
),
)
: const NoDataBox(),
loading: () =>
const Center(child: CircularProgressIndicator.adaptive()),
error: (error, stackTrace) => Center(child: Text(error.toString())),
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:boorusama/boorus/core/feats/settings/settings.dart';
import 'package:boorusama/boorus/core/provider.dart';
import 'package:boorusama/boorus/core/widgets/widgets.dart';
import 'package:boorusama/boorus/gelbooru/router.dart';
import 'package:boorusama/boorus/gelbooru/widgets/gelbooru_post_context_menu.dart';
import 'package:boorusama/dart.dart';
import 'package:boorusama/foundation/error.dart';
import 'package:boorusama/widgets/widgets.dart';
Expand Down Expand Up @@ -104,7 +105,7 @@ class _DanbooruInfinitePostListState

return ContextMenuRegion(
isEnabled: !multiSelect,
contextMenu: GeneralPostContextMenu(
contextMenu: GelbooruPostContextMenu(
hasAccount: false,
onMultiSelect: () {
_multiSelectController.enableMultiSelect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import 'package:flutter/material.dart';

// Project imports:
import 'package:boorusama/boorus/core/feats/posts/posts.dart';
import 'package:boorusama/boorus/core/widgets/comment_post_button.dart';
import 'package:boorusama/boorus/core/widgets/widgets.dart';
import 'package:boorusama/boorus/gelbooru/router.dart';
import 'package:boorusama/flutter.dart';

class GelbooruPostActionToolbar extends StatelessWidget {
Expand All @@ -24,6 +26,10 @@ class GelbooruPostActionToolbar extends StatelessWidget {
children: [
BookmarkPostButton(post: post),
DownloadPostButton(post: post),
CommentPostButton(
post: post,
onPressed: () => goToGelbooruCommentsPage(context, post.id),
),
SharePostButton(post: post),
],
),
Expand Down
15 changes: 15 additions & 0 deletions lib/boorus/gelbooru/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter/material.dart';

// Package imports:
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:scroll_to_index/scroll_to_index.dart';

// Project imports:
Expand All @@ -12,6 +13,7 @@ import 'package:boorusama/boorus/core/feats/settings/settings.dart';
import 'package:boorusama/boorus/core/widgets/widgets.dart';
import 'package:boorusama/boorus/gelbooru/gelbooru_provider.dart';
import 'package:boorusama/boorus/gelbooru/pages/artists/gelbooru_artist_page.dart';
import 'package:boorusama/boorus/gelbooru/pages/comments/gelbooru_comment_page.dart';
import 'package:boorusama/boorus/gelbooru/pages/posts.dart';
import 'package:boorusama/boorus/gelbooru/pages/search/gelbooru_search_page.dart';
import 'package:boorusama/flutter.dart';
Expand Down Expand Up @@ -57,6 +59,19 @@ void goToGelbooruArtistPage(
));
}

void goToGelbooruCommentsPage(
BuildContext context,
int postId,
) {
showMaterialModalBottomSheet(
context: context,
duration: const Duration(milliseconds: 250),
builder: (context) => GelbooruProvider(
builder: (context) => GelbooruCommentPage(postId: postId),
),
);
}

Widget provideArtistPageDependencies(
WidgetRef ref, {
required String artist,
Expand Down
Loading

0 comments on commit c63ffbd

Please sign in to comment.