Skip to content

Commit

Permalink
Merge pull request #287 from khoadng/e621
Browse files Browse the repository at this point in the history
E621
  • Loading branch information
khoadng committed Jun 21, 2023
2 parents fd789f1 + 8fc6b10 commit 9ecd94b
Show file tree
Hide file tree
Showing 84 changed files with 3,649 additions and 542 deletions.
12 changes: 12 additions & 0 deletions assets/boorus.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,17 @@
"url" : "https://lolibooru.moe/",
"cheatsheet" : "https://lolibooru.moe/help/cheatsheet",
"login_type" : "login_password_hashed"
},
{
"name" : "e621",
"url" : "https://e621.net/",
"cheatsheet" : "https://e621.net/help/cheatsheet",
"login_type" : "login_api_key"
},
{
"name" : "e926",
"url" : "https://e926.net/",
"cheatsheet" : "https://e926.net/help/cheatsheet",
"login_type" : "login_api_key"
}
]
91 changes: 91 additions & 0 deletions lib/api/e621/e621_api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// ignore_for_file: avoid_positional_boolean_parameters

// Package imports:
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';

part 'e621_api.g.dart';

@RestApi()
abstract class E621Api {
factory E621Api(
Dio dio, {
String baseUrl,
}) = _E621Api;

@POST('/favorites.json')
Future<HttpResponse> addToFavorites(
@Query('login') String? login,
@Query('api_key') String? apiKey,
@Query('post_id') int postId,
);

@DELETE('/favorites/{postId}.json')
Future<HttpResponse> removeFromFavorites(
@Path() int postId,
@Query('login') String? login,
@Query('api_key') String? apiKey,
);

@GET('/comments.json')
Future<HttpResponse> getComments(
@Query('group_by') String groupBy,
@Query('search[post_id]') int postId,
@Query('limit') int limit, {
@CancelRequest() CancelToken? cancelToken,
});

@GET('/artists.json')
Future<HttpResponse> getArtists(
@Query('search[name]') String name, {
@CancelRequest() CancelToken? cancelToken,
});

@GET('/artists/{nameOrId}.json')
Future<HttpResponse> getArtist(
@Path() String nameOrId, {
@CancelRequest() CancelToken? cancelToken,
});

@GET('/posts.json')
Future<HttpResponse> getPosts(
@Query('login') String? login,
@Query('api_key') String? apiKey,
@Query('page') int page,
@Query('tags') String tags,
@Query('limit') int limit, {
@CancelRequest() CancelToken? cancelToken,
});

@GET('/popular.json')
Future<HttpResponse> getPopularPosts(
@Query('login') String? login,
@Query('api_key') String? apiKey,
@Query('date') String date,
@Query('scale') String scale,
);

@GET('/tags.json')
Future<HttpResponse> getTagsByNamePattern(
@Query('login') String? login,
@Query('api_key') String? apiKey,
@Query('page') int page,
@Query('search[hide_empty]') String hideEmpty,
@Query('search[name_matches]') String stringPattern,
@Query('search[order]') String order,
@Query('limit') int limit,
);

@GET('/tags/autocomplete.json')
Future<HttpResponse> autocomplete(
@Query('search[name_matches]') String query,
@Query('expiry') int expiry,
);

@GET('/notes.json')
Future<HttpResponse> getNotes(
@Query('search[post_id]') int postId,
@Query('limit') int limit, {
@CancelRequest() CancelToken? cancelToken,
});
}
2 changes: 2 additions & 0 deletions lib/boorus/core/feats/booru_user_identity_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class BooruUserIdentityProviderImpl implements BooruUserIdentityProvider {
case BooruType.yandere:
case BooruType.sakugabooru:
case BooruType.lolibooru:
case BooruType.e621:
case BooruType.e926:
accountId = 0;
break;
}
Expand Down
10 changes: 10 additions & 0 deletions lib/boorus/core/feats/boorus/booru.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ enum BooruType {
sakugabooru,
rule34xxx,
lolibooru,
e621,
e926,
}

enum BooruEngine {
Expand Down Expand Up @@ -80,6 +82,8 @@ extension BooruTypeX on BooruType {
BooruType.yandere => 'Yandere',
BooruType.sakugabooru => 'Sakugabooru',
BooruType.lolibooru => 'Lolibooru',
BooruType.e621 => 'e621',
BooruType.e926 => 'e926',
};

bool get isGelbooruBased =>
Expand Down Expand Up @@ -112,6 +116,8 @@ extension BooruTypeX on BooruType {
BooruType.sakugabooru => 8,
BooruType.rule34xxx => 9,
BooruType.lolibooru => 10,
BooruType.e621 => 11,
BooruType.e926 => 12,
BooruType.unknown => 0,
};
}
Expand All @@ -133,6 +139,8 @@ BooruType intToBooruType(int value) => switch (value) {
8 => BooruType.sakugabooru,
9 => BooruType.rule34xxx,
10 => BooruType.lolibooru,
11 => BooruType.e621,
12 => BooruType.e926,
_ => BooruType.unknown
};

Expand All @@ -147,6 +155,8 @@ BooruType stringToBooruType(String value) => switch (value) {
'yandere' => BooruType.yandere,
'sakugabooru' => BooruType.sakugabooru,
'lolibooru' => BooruType.lolibooru,
'e621' => BooruType.e621,
'e926' => BooruType.e926,
_ => BooruType.unknown
};

Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions lib/boorus/core/feats/notes/note_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Package imports:
import 'package:flutter_riverpod/flutter_riverpod.dart';

// Project imports:
import 'package:boorusama/boorus/core/feats/boorus/boorus.dart';
import 'package:boorusama/boorus/core/feats/notes/notes.dart';
import 'package:boorusama/boorus/core/feats/posts/posts.dart';

final noteRepoProvider = Provider<NoteRepository>((ref) {
throw UnimplementedError();
});

final notesControllerProvider = NotifierProvider.autoDispose
.family<NotesControllerNotifier, NotesControllerState, Post>(
NotesControllerNotifier.new,
dependencies: [
noteRepoProvider,
currentBooruConfigProvider,
],
);
6 changes: 6 additions & 0 deletions lib/boorus/core/feats/notes/note_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Project imports:
import 'package:boorusama/boorus/core/feats/notes/notes.dart';

abstract interface class NoteRepository {
Future<List<Note>> getNotes(int postId);
}
5 changes: 5 additions & 0 deletions lib/boorus/core/feats/notes/notes.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export 'note.dart';
export 'note_coordinate.dart';
export 'note_provider.dart';
export 'note_repository.dart';
export 'notes_controller.dart';
61 changes: 61 additions & 0 deletions lib/boorus/core/feats/notes/notes_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Package imports:
import 'package:equatable/equatable.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/notes/notes.dart';
import 'package:boorusama/boorus/core/feats/posts/posts.dart';
import 'package:boorusama/functional.dart';

class NotesControllerState extends Equatable {
const NotesControllerState({
required this.notes,
required this.enableNotes,
});

final IList<Note> notes;
final bool enableNotes;

factory NotesControllerState.initial() => NotesControllerState(
notes: <Note>[].lock,
enableNotes: true,
);

NotesControllerState copyWith({
IList<Note>? notes,
bool? enableNotes,
}) =>
NotesControllerState(
notes: notes ?? this.notes,
enableNotes: enableNotes ?? this.enableNotes,
);

@override
List<Object?> get props => [notes, enableNotes];
}

class NotesControllerNotifier
extends AutoDisposeFamilyNotifier<NotesControllerState, Post> {
@override
NotesControllerState build(Post arg) {
ref.watch(currentBooruConfigProvider);

return NotesControllerState.initial();
}

void toggleNoteVisibility() {
state = state.copyWith(
enableNotes: !state.enableNotes,
);
}

Future<void> load() async {
if (state.notes.isEmpty && arg.isTranslated) {
final notes = await ref.read(noteRepoProvider).getNotes(arg.id);
state = state.copyWith(
notes: notes.lock,
);
}
}
}
1 change: 1 addition & 0 deletions lib/boorus/core/feats/posts/media_info_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mixin MediaInfoMixin {
bool get isFlash => format == 'swf';

bool get isWebm => format == 'webm';
bool get isMp4 => format == 'mp4';

bool get isAnimated {
return isVideo || (format == 'gif');
Expand Down
1 change: 1 addition & 0 deletions lib/boorus/core/feats/posts/sources/source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ sealed class PostSource {
static final IMap<String, String> customFaviconUrlSite = <String, String>{
'lofter': 'https://www.lofter.com/favicon.ico',
'lolibooru': 'https://lolibooru.moe/favicon.ico',
'e926': 'https://www.e926.net/favicon.ico',
}.lock;

factory PostSource.from(
Expand Down
Loading

0 comments on commit 9ecd94b

Please sign in to comment.