Skip to content

Commit

Permalink
Merge pull request #1342 from nextcloud/refactor/private-bloc-impleme…
Browse files Browse the repository at this point in the history
…ntations
  • Loading branch information
provokateurin authored Dec 28, 2023
2 parents b946014 + 8fc3cd0 commit d2a8b18
Show file tree
Hide file tree
Showing 35 changed files with 434 additions and 258 deletions.
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 {}

@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

0 comments on commit d2a8b18

Please sign in to comment.