Skip to content

Commit

Permalink
Add anonymous subscriptions bloc and allow to subscribe to communitie…
Browse files Browse the repository at this point in the history
…s from search page
  • Loading branch information
vbh committed Jul 22, 2023
1 parent 0efb165 commit 136454b
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
79 changes: 79 additions & 0 deletions lib/community/bloc/anonymous_subscriptions_bloc.dart
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()));
}
}
}
22 changes: 22 additions & 0 deletions lib/community/bloc/anonymous_subscriptions_event.dart
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});
}
35 changes: 35 additions & 0 deletions lib/community/bloc/anonymous_subscriptions_state.dart
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];
}
41 changes: 41 additions & 0 deletions lib/community/helpers/anonymous_subscriptions_helper.dart
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);
}
}

0 comments on commit 136454b

Please sign in to comment.