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.
Add anonymous subscriptions bloc and allow to subscribe to communitie…
…s from search page
- Loading branch information
Showing
4 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
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,79 @@ | ||
|
||
import 'dart:async'; | ||
import 'package:bloc/bloc.dart'; | ||
import 'package:bloc_concurrency/bloc_concurrency.dart'; | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:lemmy_api_client/v3.dart'; | ||
import 'package:stream_transform/stream_transform.dart'; | ||
import 'package:thunder/community/helpers/anonymous_subscriptions_helper.dart'; | ||
import 'package:thunder/community/models/anonymous_subscriptions.dart'; | ||
|
||
part 'anonymous_subscriptions_event.dart'; | ||
part 'anonymous_subscriptions_state.dart'; | ||
|
||
const throttleDuration = Duration(seconds: 1); | ||
|
||
EventTransformer<E> throttleDroppable<E>(Duration duration) { | ||
return (events, mapper) => droppable<E>().call(events.throttle(duration), mapper); | ||
} | ||
|
||
class AnonymousSubscriptionsBloc extends Bloc<AnonymousSubscriptionsEvent, AnonymousSubscriptionsState>{ | ||
AnonymousSubscriptionsBloc() : super(const AnonymousSubscriptionsState()){ | ||
on<GetSubscribedCommunitiesEvent>( | ||
_getSubscribedCommunities, | ||
transformer: throttleDroppable(throttleDuration) | ||
); | ||
|
||
on<AddSubscriptionsEvent>( | ||
_addSubscriptions, | ||
transformer: throttleDroppable(throttleDuration) | ||
); | ||
|
||
on<DeleteSubscriptionsEvent>( | ||
_deleteSubscriptions, | ||
transformer: throttleDroppable(throttleDuration) | ||
); | ||
} | ||
|
||
FutureOr<void> _deleteSubscriptions(DeleteSubscriptionsEvent event, Emitter<AnonymousSubscriptionsState> emit) async { | ||
try { | ||
await AnonymousSubscriptions.deleteCommunities(event.ids); | ||
emit(state.copyWith( | ||
status: AnonymousSubscriptionsStatus.success, | ||
subscriptions: [...state.subscriptions]..removeWhere((e) => event.ids.contains(e.id)), | ||
ids: {...state.ids}..removeAll(event.ids), | ||
)); | ||
emit(state.copyWith(status: AnonymousSubscriptionsStatus.success)); | ||
} catch (e) { | ||
emit(state.copyWith(status: AnonymousSubscriptionsStatus.failure, errorMessage: e.toString())); | ||
} | ||
} | ||
|
||
FutureOr<void> _addSubscriptions(AddSubscriptionsEvent event, Emitter<AnonymousSubscriptionsState> emit) async { | ||
try { | ||
await insertSubscriptions(event.communities); | ||
emit(state.copyWith( | ||
status: AnonymousSubscriptionsStatus.success, | ||
subscriptions: [...state.subscriptions, ...event.communities], | ||
ids: {...state.ids}..addAll(event.communities.map((e) => e.id)) | ||
)); | ||
|
||
} catch (e) { | ||
emit(state.copyWith(status: AnonymousSubscriptionsStatus.failure, errorMessage: e.toString())); | ||
} | ||
} | ||
|
||
Future<void> _getSubscribedCommunities(GetSubscribedCommunitiesEvent event, Emitter<AnonymousSubscriptionsState> emit) async { | ||
emit(const AnonymousSubscriptionsState(status: AnonymousSubscriptionsStatus.loading)); | ||
try { | ||
List<CommunitySafe> subscribedCommunities = await getSubscriptions(); | ||
emit(state.copyWith( | ||
status: AnonymousSubscriptionsStatus.success, | ||
subscriptions: subscribedCommunities, | ||
ids: subscribedCommunities.map((e) => e.id).toSet(), | ||
)); | ||
} catch (e) { | ||
emit(state.copyWith(status: AnonymousSubscriptionsStatus.failure, errorMessage: e.toString())); | ||
} | ||
} | ||
} |
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,22 @@ | ||
part of 'anonymous_subscriptions_bloc.dart'; | ||
|
||
abstract class AnonymousSubscriptionsEvent extends Equatable { | ||
const AnonymousSubscriptionsEvent(); | ||
|
||
@override | ||
List<Object> get props => []; | ||
} | ||
|
||
class GetSubscribedCommunitiesEvent extends AnonymousSubscriptionsEvent {} | ||
|
||
class AddSubscriptionsEvent extends AnonymousSubscriptionsEvent { | ||
final Set<CommunitySafe> communities; | ||
|
||
const AddSubscriptionsEvent({required this.communities}); | ||
} | ||
|
||
class DeleteSubscriptionsEvent extends AnonymousSubscriptionsEvent { | ||
final Set<int> ids; | ||
|
||
const DeleteSubscriptionsEvent({required this.ids}); | ||
} |
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,35 @@ | ||
part of 'anonymous_subscriptions_bloc.dart'; | ||
|
||
enum AnonymousSubscriptionsStatus { initial, loading, refreshing, success, empty, failure } | ||
|
||
class AnonymousSubscriptionsState extends Equatable { | ||
const AnonymousSubscriptionsState({ | ||
this.status = AnonymousSubscriptionsStatus.initial, | ||
this.subscriptions = const [], | ||
this.ids = const {}, | ||
this.errorMessage, | ||
}); | ||
|
||
final AnonymousSubscriptionsStatus status; | ||
final String? errorMessage; | ||
final List<CommunitySafe> subscriptions; | ||
final Set<int> ids; | ||
|
||
|
||
AnonymousSubscriptionsState copyWith({ | ||
AnonymousSubscriptionsStatus? status, | ||
List<CommunitySafe>? subscriptions, | ||
Set<int>? ids, | ||
String? errorMessage, | ||
}) { | ||
return AnonymousSubscriptionsState( | ||
status: status ?? this.status, | ||
ids: ids?? this.ids, | ||
subscriptions: subscriptions ?? this.subscriptions, | ||
errorMessage: errorMessage ?? this.errorMessage, | ||
); | ||
} | ||
|
||
@override | ||
List<Object?> get props => [status, subscriptions, ids, errorMessage]; | ||
} |
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,41 @@ | ||
import 'package:lemmy_api_client/v3.dart'; | ||
|
||
import '../models/anonymous_subscriptions.dart'; | ||
|
||
Future<List<CommunitySafe>> getSubscriptions() async { | ||
List<Community> subscribedCommunities = await AnonymousSubscriptions.getSubscribedCommunities(); | ||
return subscribedCommunities.map((e) => e.toCommunitySafe).toList(); | ||
} | ||
|
||
Future<void> insertSubscriptions(Set<CommunitySafe> communities) async { | ||
Set<Community> newCommunities = communities.map((e) => e.toCommunity).toSet(); | ||
await AnonymousSubscriptions.insertCommunities(newCommunities); | ||
} | ||
|
||
extension on Community { | ||
CommunitySafe get toCommunitySafe { | ||
return CommunitySafe( | ||
id: id, | ||
name: name, | ||
title: title, | ||
removed: false, | ||
published: DateTime.now(), | ||
deleted: false, | ||
nsfw: false, | ||
actorId: actorId, | ||
local: false, | ||
icon: icon, | ||
instanceHost: "lemmy.world"); | ||
} | ||
} | ||
|
||
extension on CommunitySafe { | ||
Community get toCommunity { | ||
return Community( | ||
id: id, | ||
name: name, | ||
title: title, | ||
icon: icon, | ||
actorId: actorId); | ||
} | ||
} |