forked from thunder-app/thunder
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Garrett Bischof
committed
Mar 23, 2024
1 parent
54b209f
commit 8b433eb
Showing
21 changed files
with
4,909 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
part of 'post_bloc.dart'; | ||
|
||
abstract class PostEvent extends Equatable { | ||
const PostEvent(); | ||
|
||
@override | ||
List<Object> get props => []; | ||
} | ||
|
||
class GetPostEvent extends PostEvent { | ||
final int? postId; | ||
final PostViewMedia? postView; | ||
final CommentSortType? sortType; | ||
final String? selectedCommentPath; | ||
final int? selectedCommentId; | ||
final int? newlyCreatedCommentId; | ||
|
||
const GetPostEvent({this.sortType, this.postView, this.postId, this.selectedCommentPath, this.selectedCommentId, this.newlyCreatedCommentId}); | ||
} | ||
|
||
class GetPostCommentsEvent extends PostEvent { | ||
final int? postId; | ||
final int? commentParentId; | ||
final bool reset; | ||
final bool viewAllCommentsRefresh; | ||
final CommentSortType? sortType; | ||
|
||
const GetPostCommentsEvent({this.postId, this.commentParentId, this.reset = false, this.viewAllCommentsRefresh = false, this.sortType}); | ||
} | ||
|
||
class VotePostEvent extends PostEvent { | ||
final int postId; | ||
final int score; | ||
|
||
const VotePostEvent({required this.postId, required this.score}); | ||
} | ||
|
||
class SavePostEvent extends PostEvent { | ||
final int postId; | ||
final bool save; | ||
|
||
const SavePostEvent({required this.postId, required this.save}); | ||
} | ||
|
||
class VoteCommentEvent extends PostEvent { | ||
final int commentId; | ||
final int score; | ||
|
||
const VoteCommentEvent({required this.commentId, required this.score}); | ||
} | ||
|
||
class SaveCommentEvent extends PostEvent { | ||
final int commentId; | ||
final bool save; | ||
|
||
const SaveCommentEvent({required this.commentId, required this.save}); | ||
} | ||
|
||
class CreateCommentEvent extends PostEvent { | ||
final String content; | ||
final int? parentCommentId; | ||
final int? selectedCommentId; | ||
final String? selectedCommentPath; | ||
|
||
const CreateCommentEvent({required this.content, this.parentCommentId, this.selectedCommentId, this.selectedCommentPath}); | ||
} | ||
|
||
class EditCommentEvent extends PostEvent { | ||
final String content; | ||
final int commentId; | ||
|
||
const EditCommentEvent({required this.content, required this.commentId}); | ||
} | ||
|
||
class DeleteCommentEvent extends PostEvent { | ||
final int commentId; | ||
final bool deleted; | ||
|
||
const DeleteCommentEvent({required this.deleted, required this.commentId}); | ||
} | ||
|
||
enum NavigateCommentDirection { up, down } | ||
|
||
class NavigateCommentEvent extends PostEvent { | ||
final NavigateCommentDirection direction; | ||
final int targetIndex; | ||
|
||
const NavigateCommentEvent({required this.targetIndex, required this.direction}); | ||
} | ||
|
||
class StartCommentSearchEvent extends PostEvent { | ||
final List<Comment> commentMatches; | ||
|
||
const StartCommentSearchEvent({required this.commentMatches}); | ||
} | ||
|
||
class ContinueCommentSearchEvent extends PostEvent { | ||
const ContinueCommentSearchEvent(); | ||
} | ||
|
||
class EndCommentSearchEvent extends PostEvent { | ||
const EndCommentSearchEvent(); | ||
} | ||
|
||
class ReportCommentEvent extends PostEvent { | ||
final int commentId; | ||
final String message; | ||
|
||
const ReportCommentEvent({ | ||
required this.commentId, | ||
required this.message, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
part of 'post_bloc.dart'; | ||
|
||
enum PostStatus { | ||
initial, | ||
loading, | ||
refreshing, | ||
success, | ||
empty, | ||
failure, | ||
searchInProgress, | ||
} | ||
|
||
class PostState extends Equatable { | ||
const PostState({ | ||
this.status = PostStatus.initial, | ||
this.postId, | ||
this.postView, | ||
this.comments = const [], | ||
this.commentResponseMap = const <int, CommentView>{}, | ||
this.commentPage = 1, | ||
this.commentCount = 0, | ||
this.communityId, | ||
this.moderators, | ||
this.crossPosts, | ||
this.hasReachedCommentEnd = false, | ||
this.errorMessage, | ||
this.sortType, | ||
this.sortTypeIcon, | ||
this.selectedCommentId, | ||
this.selectedCommentPath, | ||
this.newlyCreatedCommentId, | ||
this.moddingCommentId = -1, | ||
this.viewAllCommentsRefresh = false, | ||
this.navigateCommentIndex = 0, | ||
this.navigateCommentId = 0, | ||
this.commentMatches, | ||
}); | ||
|
||
final PostStatus status; | ||
|
||
final bool viewAllCommentsRefresh; | ||
|
||
final CommentSortType? sortType; | ||
final IconData? sortTypeIcon; | ||
|
||
final int? postId; | ||
final int? communityId; | ||
final List<CommunityModeratorView>? moderators; | ||
final List<PostView>? crossPosts; | ||
final PostViewMedia? postView; | ||
|
||
// Comment related data | ||
final List<CommentViewTree> comments; | ||
final Map<int, CommentView> commentResponseMap; | ||
final int commentPage; | ||
final int commentCount; | ||
final bool hasReachedCommentEnd; | ||
final int? selectedCommentId; | ||
final int? newlyCreatedCommentId; | ||
final String? selectedCommentPath; | ||
|
||
// This is to track what comment is being restored or deleted so we can | ||
// show a spinner indicator that thunder is working on it | ||
final int moddingCommentId; | ||
|
||
final String? errorMessage; | ||
|
||
final int navigateCommentIndex; | ||
final List<Comment>? commentMatches; | ||
|
||
// This exists purely for forcing the bloc to refire | ||
// even if the comment index doesn't change | ||
final int navigateCommentId; | ||
|
||
PostState copyWith({ | ||
required PostStatus status, | ||
int? postId, | ||
PostViewMedia? postView, | ||
List<CommentViewTree>? comments, | ||
Map<int, CommentView>? commentResponseMap, | ||
int? commentPage, | ||
int? commentCount, | ||
bool? hasReachedCommentEnd, | ||
int? communityId, | ||
List<CommunityModeratorView>? moderators, | ||
List<PostView>? crossPosts, | ||
String? errorMessage, | ||
CommentSortType? sortType, | ||
IconData? sortTypeIcon, | ||
int? selectedCommentId, | ||
String? selectedCommentPath, | ||
int? newlyCreatedCommentId, | ||
int? moddingCommentId, | ||
bool? viewAllCommentsRefresh = false, | ||
int? navigateCommentIndex, | ||
int? navigateCommentId, | ||
List<Comment>? commentMatches, | ||
}) { | ||
return PostState( | ||
status: status, | ||
postId: postId ?? this.postId, | ||
postView: postView ?? this.postView, | ||
comments: comments ?? this.comments, | ||
commentResponseMap: commentResponseMap ?? this.commentResponseMap, | ||
commentPage: commentPage ?? this.commentPage, | ||
commentCount: commentCount ?? this.commentCount, | ||
hasReachedCommentEnd: hasReachedCommentEnd ?? this.hasReachedCommentEnd, | ||
communityId: communityId ?? this.communityId, | ||
moderators: moderators ?? this.moderators, | ||
crossPosts: crossPosts ?? this.crossPosts, | ||
errorMessage: errorMessage ?? this.errorMessage, | ||
sortType: sortType ?? this.sortType, | ||
sortTypeIcon: sortTypeIcon ?? this.sortTypeIcon, | ||
selectedCommentId: selectedCommentId, | ||
selectedCommentPath: selectedCommentPath, | ||
newlyCreatedCommentId: newlyCreatedCommentId, | ||
moddingCommentId: moddingCommentId ?? this.moddingCommentId, | ||
viewAllCommentsRefresh: viewAllCommentsRefresh ?? false, | ||
navigateCommentIndex: navigateCommentIndex ?? 0, | ||
navigateCommentId: navigateCommentId ?? 0, | ||
commentMatches: commentMatches ?? this.commentMatches, | ||
); | ||
} | ||
|
||
@override | ||
List<Object?> get props => [ | ||
status, | ||
postId, | ||
postView, | ||
comments, | ||
commentPage, | ||
commentCount, | ||
communityId, | ||
moderators, | ||
crossPosts, | ||
errorMessage, | ||
hasReachedCommentEnd, | ||
sortType, | ||
sortTypeIcon, | ||
selectedCommentId, | ||
selectedCommentPath, | ||
newlyCreatedCommentId, | ||
viewAllCommentsRefresh, | ||
moddingCommentId, | ||
navigateCommentIndex, | ||
navigateCommentId, | ||
commentMatches, | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import 'package:bloc/bloc.dart'; | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:lemmy_api_client/pictrs.dart'; | ||
import 'package:lemmy_api_client/v3.dart'; | ||
|
||
import 'package:thunder/account/models/account.dart'; | ||
import 'package:thunder/core/auth/helpers/fetch_account.dart'; | ||
import 'package:thunder/core/models/post_view_media.dart'; | ||
import 'package:thunder/post/utils/post.dart'; | ||
import 'package:thunder/feed/utils/request.dart'; | ||
import 'package:thunder/utils/error_messages.dart'; | ||
|
||
part 'create_request_state.dart'; | ||
|
||
class CreateRequestCubit extends Cubit<CreateRequestState> { | ||
CreateRequestCubit() : super(const CreateRequestState(status: CreateRequestStatus.initial)); | ||
|
||
Future<void> clearMessage() async { | ||
emit(state.copyWith(status: CreateRequestStatus.initial, message: null)); | ||
} | ||
|
||
Future<void> uploadImage(String imageFile, {bool isRequestImage = false}) async { | ||
Account? account = await fetchActiveProfileAccount(); | ||
if (account == null) return; | ||
|
||
PictrsApi pictrs = PictrsApi(account.instance!); | ||
|
||
isRequestImage | ||
? emit(state.copyWith(status: CreateRequestStatus.postImageUploadInProgress)) | ||
: emit(state.copyWith(status: CreateRequestStatus.imageUploadInProgress)); | ||
|
||
try { | ||
PictrsUpload result = await pictrs.upload(filePath: imageFile, auth: account.jwt); | ||
String url = "https://${account.instance!}/pictrs/image/${result.files[0].file}"; | ||
|
||
isRequestImage | ||
? emit(state.copyWith(status: CreateRequestStatus.postImageUploadSuccess, imageUrl: url)) | ||
: emit(state.copyWith(status: CreateRequestStatus.imageUploadSuccess, imageUrl: url)); | ||
} catch (e) { | ||
isRequestImage | ||
? emit(state.copyWith( | ||
status: CreateRequestStatus.postImageUploadFailure, message: e.toString())) | ||
: emit(state.copyWith( | ||
status: CreateRequestStatus.imageUploadFailure, message: e.toString())); | ||
} | ||
} | ||
|
||
/// Creates or edits a post. When successful, it emits the newly created/updated post in the form of a [RequestViewMedia] | ||
/// and returns the newly created post id. | ||
Future<int?> createOrEditRequest( | ||
{required int communityId, | ||
required String name, | ||
String? body, | ||
String? url, | ||
bool? nsfw, | ||
int? postIdBeingEdited, | ||
int? languageId}) async { | ||
emit(state.copyWith(status: CreateRequestStatus.submitting)); | ||
|
||
try { | ||
PostView postView = await createRequest( | ||
communityId: communityId, | ||
name: name, | ||
body: body, | ||
url: url, | ||
nsfw: nsfw, | ||
postIdBeingEdited: postIdBeingEdited, | ||
languageId: languageId, | ||
); | ||
|
||
// Parse the newly created post | ||
List<PostViewMedia> postViewMedias = await parsePostViews([postView]); | ||
|
||
emit(state.copyWith( | ||
status: CreateRequestStatus.success, postViewMedia: postViewMedias.firstOrNull)); | ||
return postViewMedias.firstOrNull?.postView.post.id; | ||
} catch (e) { | ||
emit(state.copyWith(status: CreateRequestStatus.error, message: getExceptionErrorMessage(e))); | ||
} | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.