Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Make bloc implementations private #1342

Merged
merged 1 commit into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions packages/neon/neon_dashboard/lib/src/blocs/dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ import 'package:neon_framework/models.dart';
import 'package:nextcloud/dashboard.dart' as dashboard;
import 'package:rxdart/rxdart.dart';

/// Events for [DashboardBloc].
abstract class DashboardBlocEvents {}
/// Bloc for fetching dashboard widgets and their items.
sealed class DashboardBloc implements InteractiveBloc {
/// Creates a new Dashboard Bloc instance.
factory DashboardBloc(final Account account) => _DashboardBloc(account);

/// States for [DashboardBloc].
abstract class DashboardBlocStates {
/// Dashboard widgets that are displayed.
BehaviorSubject<Result<Map<dashboard.Widget, dashboard.WidgetItems?>>> get widgets;
}

/// Implements the business logic for fetching dashboard widgets and their items.
class DashboardBloc extends InteractiveBloc implements DashboardBlocEvents, DashboardBlocStates {
/// Creates a new Dashboard Bloc instance.
///
/// Automatically starts fetching the widgets and their items and refreshes everything every 30 seconds.
DashboardBloc(this._account) {
/// Implementation of [DashboardBloc].
///
/// Automatically starts fetching the widgets and their items and refreshes everything every 30 seconds.
class _DashboardBloc extends InteractiveBloc implements DashboardBloc {
_DashboardBloc(this._account) {
unawaited(refresh());

_timer = TimerBloc().registerTimer(const Duration(seconds: 30), refresh);
Expand Down
1 change: 1 addition & 0 deletions packages/neon/neon_dashboard/test/widget_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:neon_framework/widgets.dart';
import 'package:nextcloud/dashboard.dart' as dashboard;
import 'package:rxdart/rxdart.dart';

// ignore: subtype_of_sealed_class
class MockAccountsBloc extends Mock implements AccountsBloc {}

class MockCacheManager extends Mock implements DefaultCacheManager {}
Expand Down
22 changes: 17 additions & 5 deletions packages/neon/neon_files/lib/src/blocs/browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,31 @@ import 'package:neon_framework/utils.dart';
import 'package:nextcloud/webdav.dart';
import 'package:rxdart/rxdart.dart';

abstract interface class FilesBrowserBlocEvents {
sealed class FilesBrowserBloc implements InteractiveBloc {
factory FilesBrowserBloc(
final FilesOptions options,
final Account account, {
final PathUri? initialPath,
}) =>
_FilesBrowserBloc(
options,
account,
initialPath: initialPath,
);

void setPath(final PathUri uri);

void createFolder(final PathUri uri);
}

abstract interface class FilesBrowserBlocStates {
BehaviorSubject<Result<List<WebDavFile>>> get files;

BehaviorSubject<PathUri> get uri;

FilesOptions get options;
}

class FilesBrowserBloc extends InteractiveBloc implements FilesBrowserBlocEvents, FilesBrowserBlocStates {
FilesBrowserBloc(
class _FilesBrowserBloc extends InteractiveBloc implements FilesBrowserBloc {
_FilesBrowserBloc(
this.options,
this.account, {
final PathUri? initialPath,
Expand All @@ -32,6 +43,7 @@ class FilesBrowserBloc extends InteractiveBloc implements FilesBrowserBlocEvents
unawaited(refresh());
}

@override
final FilesOptions options;
final Account account;

Expand Down
26 changes: 21 additions & 5 deletions packages/neon/neon_files/lib/src/blocs/files.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ import 'package:rxdart/rxdart.dart';
import 'package:share_plus/share_plus.dart';
import 'package:universal_io/io.dart';

abstract interface class FilesBlocEvents {
sealed class FilesBloc implements InteractiveBloc {
factory FilesBloc(
final FilesOptions options,
final Account account,
) =>
_FilesBloc(
options,
account,
);

void uploadFile(final PathUri uri, final String localPath);

void syncFile(final PathUri uri);
Expand All @@ -38,23 +47,29 @@ abstract interface class FilesBlocEvents {
void addFavorite(final PathUri uri);

void removeFavorite(final PathUri uri);
}

abstract interface class FilesBlocStates {
BehaviorSubject<List<FilesTask>> get tasks;

FilesOptions get options;

FilesBrowserBloc get browser;

FilesBrowserBloc getNewFilesBrowserBloc({final PathUri? initialUri});
}

class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocStates {
FilesBloc(
class _FilesBloc extends InteractiveBloc implements FilesBloc {
_FilesBloc(
this.options,
this.account,
) {
options.uploadQueueParallelism.addListener(_uploadParallelismListener);
options.downloadQueueParallelism.addListener(_downloadParallelismListener);
}

@override
final FilesOptions options;
final Account account;
@override
late final browser = getNewFilesBrowserBloc();

final _uploadQueue = Queue();
Expand Down Expand Up @@ -217,6 +232,7 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
tasks.add(tasks.value..remove(task));
}

@override
FilesBrowserBloc getNewFilesBrowserBloc({
final PathUri? initialUri,
}) =>
Expand Down
32 changes: 22 additions & 10 deletions packages/neon/neon_news/lib/src/blocs/article.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,40 @@ import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:neon_framework/blocs.dart';
import 'package:neon_framework/models.dart';
import 'package:neon_news/src/blocs/articles.dart';
import 'package:nextcloud/news.dart' as news;
import 'package:rxdart/rxdart.dart';

abstract interface class NewsArticleBlocEvents {
sealed class NewsArticleBloc implements InteractiveBloc {
factory NewsArticleBloc(
final NewsArticlesBloc articlesBloc,
final Account account,
final news.Article article,
) =>
_NewsArticleBloc(
articlesBloc,
account,
article,
);

void markArticleAsRead();

void markArticleAsUnread();

void starArticle();

void unstarArticle();
}

abstract interface class NewsArticleBlocStates {
BehaviorSubject<bool> get unread;

BehaviorSubject<bool> get starred;
}

class NewsArticleBloc extends InteractiveBloc implements NewsArticleBlocEvents, NewsArticleBlocStates {
NewsArticleBloc(
class _NewsArticleBloc extends InteractiveBloc implements NewsArticleBloc {
_NewsArticleBloc(
this._newsArticlesBloc,
this.account,
final news.Article article,
) {
_id = article.id;
Expand All @@ -33,6 +44,7 @@ class NewsArticleBloc extends InteractiveBloc implements NewsArticleBlocEvents,
}

final NewsArticlesBloc _newsArticlesBloc;
final Account account;

late final int _id;

Expand All @@ -50,36 +62,36 @@ class NewsArticleBloc extends InteractiveBloc implements NewsArticleBlocEvents,
BehaviorSubject<bool> unread = BehaviorSubject<bool>();

@override
void refresh() {}
Future<void> refresh() async {}
provokateurin marked this conversation as resolved.
Show resolved Hide resolved

@override
void markArticleAsRead() {
_wrapArticleAction(() async {
await _newsArticlesBloc.account.client.news.markArticleAsRead(itemId: _id);
await account.client.news.markArticleAsRead(itemId: _id);
unread.add(false);
});
}

@override
void markArticleAsUnread() {
_wrapArticleAction(() async {
await _newsArticlesBloc.account.client.news.markArticleAsUnread(itemId: _id);
await account.client.news.markArticleAsUnread(itemId: _id);
unread.add(true);
});
}

@override
void starArticle() {
_wrapArticleAction(() async {
await _newsArticlesBloc.account.client.news.starArticle(itemId: _id);
await account.client.news.starArticle(itemId: _id);
starred.add(true);
});
}

@override
void unstarArticle() {
_wrapArticleAction(() async {
await _newsArticlesBloc.account.client.news.unstarArticle(itemId: _id);
await account.client.news.unstarArticle(itemId: _id);
starred.add(false);
});
}
Expand Down
31 changes: 25 additions & 6 deletions packages/neon/neon_news/lib/src/blocs/articles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,22 @@ enum ListType {
folder,
}

abstract interface class NewsArticlesBlocEvents {
sealed class NewsArticlesBloc implements InteractiveBloc {
factory NewsArticlesBloc(
final NewsBloc newsBloc,
final NewsOptions options,
final Account account, {
final int? id,
final ListType? listType,
}) =>
_NewsArticlesBloc(
newsBloc,
options,
account,
id: id,
listType: listType,
);

void setFilterType(final FilterType type);

void markArticleAsRead(final news.Article article);
Expand All @@ -29,24 +44,26 @@ abstract interface class NewsArticlesBlocEvents {
void starArticle(final news.Article article);

void unstarArticle(final news.Article article);
}

abstract interface class NewsArticlesBlocStates {
BehaviorSubject<Result<List<news.Article>>> get articles;

BehaviorSubject<FilterType> get filterType;

NewsOptions get options;

ListType? get listType;
}

class NewsMainArticlesBloc extends NewsArticlesBloc {
class NewsMainArticlesBloc extends _NewsArticlesBloc {
NewsMainArticlesBloc(
super._newsBloc,
super.options,
super.account,
);
}

class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents, NewsArticlesBlocStates {
NewsArticlesBloc(
class _NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBloc {
_NewsArticlesBloc(
this._newsBloc,
this.options,
this.account, {
Expand All @@ -64,9 +81,11 @@ class NewsArticlesBloc extends InteractiveBloc implements NewsArticlesBlocEvents
}

final NewsBloc _newsBloc;
@override
final NewsOptions options;
final Account account;
final int? id;
@override
final ListType? listType;

@override
Expand Down
23 changes: 17 additions & 6 deletions packages/neon/neon_news/lib/src/blocs/news.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ import 'package:neon_news/src/options.dart';
import 'package:nextcloud/news.dart' as news;
import 'package:rxdart/rxdart.dart';

abstract interface class NewsBlocEvents {
sealed class NewsBloc implements InteractiveBloc {
factory NewsBloc(
final NewsOptions options,
final Account account,
) =>
_NewsBloc(
options,
account,
);

void addFeed(final String url, final int? folderId);

void removeFeed(final int feedId);
Expand All @@ -26,18 +35,20 @@ abstract interface class NewsBlocEvents {
void renameFolder(final int folderId, final String name);

void markFolderAsRead(final int folderId);
}

abstract interface class NewsBlocStates {
BehaviorSubject<Result<List<news.Folder>>> get folders;

BehaviorSubject<Result<List<news.Feed>>> get feeds;

BehaviorSubject<int> get unreadCounter;

NewsOptions get options;

NewsMainArticlesBloc get mainArticlesBloc;
}

class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates, NewsMainArticlesBloc {
NewsBloc(
class _NewsBloc extends InteractiveBloc implements NewsBloc, NewsMainArticlesBloc {
_NewsBloc(
this.options,
this.account,
) {
Expand All @@ -55,8 +66,8 @@ class NewsBloc extends InteractiveBloc implements NewsBlocEvents, NewsBlocStates
@override
final NewsOptions options;
@override
@override
final Account account;
@override
late final mainArticlesBloc = NewsMainArticlesBloc(
this,
options,
Expand Down
4 changes: 3 additions & 1 deletion packages/neon/neon_news/lib/src/pages/feed.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:neon_framework/blocs.dart';
import 'package:neon_framework/utils.dart';
import 'package:neon_news/src/blocs/articles.dart';
import 'package:neon_news/src/blocs/news.dart';
import 'package:neon_news/src/widgets/articles_view.dart';
Expand All @@ -25,7 +27,7 @@ class NewsFeedPage extends StatelessWidget {
bloc: NewsArticlesBloc(
bloc,
bloc.options,
bloc.account,
NeonProvider.of<AccountsBloc>(context).activeAccount.value!,
id: feed.id,
listType: ListType.feed,
),
Expand Down
Loading