jld3103
2 years ago
committed by
GitHub
15 changed files with 588 additions and 162 deletions
@ -0,0 +1,103 @@ |
|||||||
|
import 'dart:async'; |
||||||
|
|
||||||
|
import 'package:neon/src/apps/news/blocs/articles.dart'; |
||||||
|
import 'package:neon/src/neon.dart'; |
||||||
|
import 'package:nextcloud/nextcloud.dart'; |
||||||
|
import 'package:rx_bloc/rx_bloc.dart'; |
||||||
|
import 'package:rxdart/rxdart.dart'; |
||||||
|
|
||||||
|
part 'article.rxb.g.dart'; |
||||||
|
|
||||||
|
abstract class NewsArticleBlocEvents { |
||||||
|
void markArticleAsRead(); |
||||||
|
|
||||||
|
void markArticleAsUnread(); |
||||||
|
|
||||||
|
void starArticle(); |
||||||
|
|
||||||
|
void unstarArticle(); |
||||||
|
} |
||||||
|
|
||||||
|
abstract class NewsArticleBlocStates { |
||||||
|
BehaviorSubject<bool> get unread; |
||||||
|
|
||||||
|
BehaviorSubject<bool> get starred; |
||||||
|
|
||||||
|
Stream<Exception> get errors; |
||||||
|
} |
||||||
|
|
||||||
|
@RxBloc() |
||||||
|
class NewsArticleBloc extends $NewsArticleBloc { |
||||||
|
NewsArticleBloc( |
||||||
|
this._requestManager, |
||||||
|
this._client, |
||||||
|
this._newsArticlesBloc, |
||||||
|
final NewsArticle article, |
||||||
|
) { |
||||||
|
_$markArticleAsReadEvent.listen((final _) { |
||||||
|
_wrapArticleAction(() async { |
||||||
|
await _client.news.markArticleAsRead(itemId: article.id); |
||||||
|
_unreadSubject.add(false); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
_$markArticleAsUnreadEvent.listen((final _) { |
||||||
|
_wrapArticleAction(() async { |
||||||
|
await _client.news.markArticleAsUnread(itemId: article.id); |
||||||
|
_unreadSubject.add(true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
_$starArticleEvent.listen((final _) { |
||||||
|
_wrapArticleAction(() async { |
||||||
|
await _client.news.starArticle(itemId: article.id); |
||||||
|
_starredSubject.add(true); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
_$unstarArticleEvent.listen((final _) { |
||||||
|
_wrapArticleAction(() async { |
||||||
|
await _client.news.unstarArticle(itemId: article.id); |
||||||
|
_starredSubject.add(false); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
_unreadSubject.add(article.unread); |
||||||
|
_starredSubject.add(article.starred); |
||||||
|
url = article.url; |
||||||
|
} |
||||||
|
|
||||||
|
void _wrapArticleAction(final Future Function() call) { |
||||||
|
final stream = _requestManager.wrapWithoutCache(() async => call()).asBroadcastStream(); |
||||||
|
stream.whereError().listen(_errorsStreamController.add); |
||||||
|
stream.whereSuccess().listen((final _) async { |
||||||
|
_newsArticlesBloc.refresh(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
final RequestManager _requestManager; |
||||||
|
final NextcloudClient _client; |
||||||
|
final NewsArticlesBloc _newsArticlesBloc; |
||||||
|
|
||||||
|
late final String url; |
||||||
|
final _unreadSubject = BehaviorSubject<bool>(); |
||||||
|
final _starredSubject = BehaviorSubject<bool>(); |
||||||
|
final _errorsStreamController = StreamController<Exception>(); |
||||||
|
|
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
unawaited(_unreadSubject.close()); |
||||||
|
unawaited(_starredSubject.close()); |
||||||
|
unawaited(_errorsStreamController.close()); |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<bool> _mapToUnreadState() => _unreadSubject; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<bool> _mapToStarredState() => _starredSubject; |
||||||
|
|
||||||
|
@override |
||||||
|
Stream<Exception> _mapToErrorsState() => _errorsStreamController.stream.asBroadcastStream(); |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||||
|
|
||||||
|
// ************************************************************************** |
||||||
|
// Generator: RxBlocGeneratorForAnnotation |
||||||
|
// ************************************************************************** |
||||||
|
|
||||||
|
part of 'article.dart'; |
||||||
|
|
||||||
|
/// Used as a contractor for the bloc, events and states classes |
||||||
|
/// {@nodoc} |
||||||
|
abstract class NewsArticleBlocType extends RxBlocTypeBase { |
||||||
|
NewsArticleBlocEvents get events; |
||||||
|
NewsArticleBlocStates get states; |
||||||
|
} |
||||||
|
|
||||||
|
/// [$NewsArticleBloc] extended by the [NewsArticleBloc] |
||||||
|
/// {@nodoc} |
||||||
|
abstract class $NewsArticleBloc extends RxBlocBase |
||||||
|
implements NewsArticleBlocEvents, NewsArticleBlocStates, NewsArticleBlocType { |
||||||
|
final _compositeSubscription = CompositeSubscription(); |
||||||
|
|
||||||
|
/// Тhe [Subject] where events sink to by calling [markArticleAsRead] |
||||||
|
final _$markArticleAsReadEvent = PublishSubject<void>(); |
||||||
|
|
||||||
|
/// Тhe [Subject] where events sink to by calling [markArticleAsUnread] |
||||||
|
final _$markArticleAsUnreadEvent = PublishSubject<void>(); |
||||||
|
|
||||||
|
/// Тhe [Subject] where events sink to by calling [starArticle] |
||||||
|
final _$starArticleEvent = PublishSubject<void>(); |
||||||
|
|
||||||
|
/// Тhe [Subject] where events sink to by calling [unstarArticle] |
||||||
|
final _$unstarArticleEvent = PublishSubject<void>(); |
||||||
|
|
||||||
|
/// The state of [unread] implemented in [_mapToUnreadState] |
||||||
|
late final BehaviorSubject<bool> _unreadState = _mapToUnreadState(); |
||||||
|
|
||||||
|
/// The state of [starred] implemented in [_mapToStarredState] |
||||||
|
late final BehaviorSubject<bool> _starredState = _mapToStarredState(); |
||||||
|
|
||||||
|
/// The state of [errors] implemented in [_mapToErrorsState] |
||||||
|
late final Stream<Exception> _errorsState = _mapToErrorsState(); |
||||||
|
|
||||||
|
@override |
||||||
|
void markArticleAsRead() => _$markArticleAsReadEvent.add(null); |
||||||
|
|
||||||
|
@override |
||||||
|
void markArticleAsUnread() => _$markArticleAsUnreadEvent.add(null); |
||||||
|
|
||||||
|
@override |
||||||
|
void starArticle() => _$starArticleEvent.add(null); |
||||||
|
|
||||||
|
@override |
||||||
|
void unstarArticle() => _$unstarArticleEvent.add(null); |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<bool> get unread => _unreadState; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<bool> get starred => _starredState; |
||||||
|
|
||||||
|
@override |
||||||
|
Stream<Exception> get errors => _errorsState; |
||||||
|
|
||||||
|
BehaviorSubject<bool> _mapToUnreadState(); |
||||||
|
|
||||||
|
BehaviorSubject<bool> _mapToStarredState(); |
||||||
|
|
||||||
|
Stream<Exception> _mapToErrorsState(); |
||||||
|
|
||||||
|
@override |
||||||
|
NewsArticleBlocEvents get events => this; |
||||||
|
|
||||||
|
@override |
||||||
|
NewsArticleBlocStates get states => this; |
||||||
|
|
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
_$markArticleAsReadEvent.close(); |
||||||
|
_$markArticleAsUnreadEvent.close(); |
||||||
|
_$starArticleEvent.close(); |
||||||
|
_$unstarArticleEvent.close(); |
||||||
|
_compositeSubscription.dispose(); |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
import 'dart:async'; |
||||||
|
|
||||||
|
import 'package:neon/src/apps/notes/app.dart'; |
||||||
|
import 'package:neon/src/apps/notes/blocs/notes.dart'; |
||||||
|
import 'package:neon/src/neon.dart'; |
||||||
|
import 'package:nextcloud/nextcloud.dart'; |
||||||
|
import 'package:rx_bloc/rx_bloc.dart'; |
||||||
|
import 'package:rxdart/rxdart.dart'; |
||||||
|
|
||||||
|
part 'note.rxb.g.dart'; |
||||||
|
|
||||||
|
abstract class NotesNoteBlocEvents { |
||||||
|
void updateNote( |
||||||
|
final int id, |
||||||
|
final String etag, { |
||||||
|
final String? title, |
||||||
|
final String? category, |
||||||
|
final String? content, |
||||||
|
final bool? favorite, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
abstract class NotesNoteBlocStates { |
||||||
|
BehaviorSubject<String> get content; |
||||||
|
|
||||||
|
BehaviorSubject<String> get title; |
||||||
|
|
||||||
|
BehaviorSubject<String> get category; |
||||||
|
|
||||||
|
BehaviorSubject<String> get etag; |
||||||
|
|
||||||
|
Stream<Exception> get errors; |
||||||
|
} |
||||||
|
|
||||||
|
@RxBloc() |
||||||
|
class NotesNoteBloc extends $NotesNoteBloc { |
||||||
|
NotesNoteBloc( |
||||||
|
this.options, |
||||||
|
this._requestManager, |
||||||
|
this._client, |
||||||
|
this._notesBloc, |
||||||
|
final NotesNote note, |
||||||
|
) { |
||||||
|
_$updateNoteEvent.listen((final event) { |
||||||
|
_wrapAction( |
||||||
|
() async { |
||||||
|
_emitNote( |
||||||
|
await _client.notes.updateNote( |
||||||
|
id: event.id, |
||||||
|
title: event.title, |
||||||
|
category: event.category, |
||||||
|
content: event.content, |
||||||
|
favorite: event.favorite ?? false ? 1 : 0, |
||||||
|
ifMatch: '"${event.etag}"', |
||||||
|
), |
||||||
|
); |
||||||
|
}, |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
_emitNote(note); |
||||||
|
id = note.id; |
||||||
|
} |
||||||
|
|
||||||
|
void _emitNote(final NotesNote note) { |
||||||
|
_contentSubject.add(note.content); |
||||||
|
_titleSubject.add(note.title); |
||||||
|
_categorySubject.add(note.category); |
||||||
|
_etagSubject.add(note.etag); |
||||||
|
} |
||||||
|
|
||||||
|
void _wrapAction(final Future Function() call) { |
||||||
|
final stream = _requestManager.wrapWithoutCache(call).asBroadcastStream(); |
||||||
|
stream.whereError().listen(_errorsStreamController.add); |
||||||
|
stream.whereSuccess().listen((final _) async { |
||||||
|
_notesBloc.refresh(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
final NotesAppSpecificOptions options; |
||||||
|
final RequestManager _requestManager; |
||||||
|
final NextcloudClient _client; |
||||||
|
final NotesBloc _notesBloc; |
||||||
|
|
||||||
|
late final int id; |
||||||
|
final _contentSubject = BehaviorSubject<String>(); |
||||||
|
final _titleSubject = BehaviorSubject<String>(); |
||||||
|
final _categorySubject = BehaviorSubject<String>(); |
||||||
|
final _etagSubject = BehaviorSubject<String>(); |
||||||
|
final _errorsStreamController = StreamController<Exception>(); |
||||||
|
|
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
unawaited(_contentSubject.close()); |
||||||
|
unawaited(_titleSubject.close()); |
||||||
|
unawaited(_categorySubject.close()); |
||||||
|
unawaited(_etagSubject.close()); |
||||||
|
unawaited(_errorsStreamController.close()); |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
Stream<Exception> _mapToErrorsState() => _errorsStreamController.stream.asBroadcastStream(); |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> _mapToContentState() => _contentSubject; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> _mapToTitleState() => _titleSubject; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> _mapToCategoryState() => _categorySubject; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> _mapToEtagState() => _etagSubject; |
||||||
|
} |
@ -0,0 +1,120 @@ |
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||||
|
|
||||||
|
// ************************************************************************** |
||||||
|
// Generator: RxBlocGeneratorForAnnotation |
||||||
|
// ************************************************************************** |
||||||
|
|
||||||
|
part of 'note.dart'; |
||||||
|
|
||||||
|
/// Used as a contractor for the bloc, events and states classes |
||||||
|
/// {@nodoc} |
||||||
|
abstract class NotesNoteBlocType extends RxBlocTypeBase { |
||||||
|
NotesNoteBlocEvents get events; |
||||||
|
NotesNoteBlocStates get states; |
||||||
|
} |
||||||
|
|
||||||
|
/// [$NotesNoteBloc] extended by the [NotesNoteBloc] |
||||||
|
/// {@nodoc} |
||||||
|
abstract class $NotesNoteBloc extends RxBlocBase |
||||||
|
implements NotesNoteBlocEvents, NotesNoteBlocStates, NotesNoteBlocType { |
||||||
|
final _compositeSubscription = CompositeSubscription(); |
||||||
|
|
||||||
|
/// Тhe [Subject] where events sink to by calling [updateNote] |
||||||
|
final _$updateNoteEvent = PublishSubject<_UpdateNoteEventArgs>(); |
||||||
|
|
||||||
|
/// The state of [content] implemented in [_mapToContentState] |
||||||
|
late final BehaviorSubject<String> _contentState = _mapToContentState(); |
||||||
|
|
||||||
|
/// The state of [title] implemented in [_mapToTitleState] |
||||||
|
late final BehaviorSubject<String> _titleState = _mapToTitleState(); |
||||||
|
|
||||||
|
/// The state of [category] implemented in [_mapToCategoryState] |
||||||
|
late final BehaviorSubject<String> _categoryState = _mapToCategoryState(); |
||||||
|
|
||||||
|
/// The state of [etag] implemented in [_mapToEtagState] |
||||||
|
late final BehaviorSubject<String> _etagState = _mapToEtagState(); |
||||||
|
|
||||||
|
/// The state of [errors] implemented in [_mapToErrorsState] |
||||||
|
late final Stream<Exception> _errorsState = _mapToErrorsState(); |
||||||
|
|
||||||
|
@override |
||||||
|
void updateNote( |
||||||
|
int id, |
||||||
|
String etag, { |
||||||
|
String? title, |
||||||
|
String? category, |
||||||
|
String? content, |
||||||
|
bool? favorite, |
||||||
|
}) => |
||||||
|
_$updateNoteEvent.add(_UpdateNoteEventArgs( |
||||||
|
id, |
||||||
|
etag, |
||||||
|
title: title, |
||||||
|
category: category, |
||||||
|
content: content, |
||||||
|
favorite: favorite, |
||||||
|
)); |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> get content => _contentState; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> get title => _titleState; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> get category => _categoryState; |
||||||
|
|
||||||
|
@override |
||||||
|
BehaviorSubject<String> get etag => _etagState; |
||||||
|
|
||||||
|
@override |
||||||
|
Stream<Exception> get errors => _errorsState; |
||||||
|
|
||||||
|
BehaviorSubject<String> _mapToContentState(); |
||||||
|
|
||||||
|
BehaviorSubject<String> _mapToTitleState(); |
||||||
|
|
||||||
|
BehaviorSubject<String> _mapToCategoryState(); |
||||||
|
|
||||||
|
BehaviorSubject<String> _mapToEtagState(); |
||||||
|
|
||||||
|
Stream<Exception> _mapToErrorsState(); |
||||||
|
|
||||||
|
@override |
||||||
|
NotesNoteBlocEvents get events => this; |
||||||
|
|
||||||
|
@override |
||||||
|
NotesNoteBlocStates get states => this; |
||||||
|
|
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
_$updateNoteEvent.close(); |
||||||
|
_compositeSubscription.dispose(); |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Helps providing the arguments in the [Subject.add] for |
||||||
|
/// [NotesNoteBlocEvents.updateNote] event |
||||||
|
class _UpdateNoteEventArgs { |
||||||
|
const _UpdateNoteEventArgs( |
||||||
|
this.id, |
||||||
|
this.etag, { |
||||||
|
this.title, |
||||||
|
this.category, |
||||||
|
this.content, |
||||||
|
this.favorite, |
||||||
|
}); |
||||||
|
|
||||||
|
final int id; |
||||||
|
|
||||||
|
final String etag; |
||||||
|
|
||||||
|
final String? title; |
||||||
|
|
||||||
|
final String? category; |
||||||
|
|
||||||
|
final String? content; |
||||||
|
|
||||||
|
final bool? favorite; |
||||||
|
} |
Loading…
Reference in new issue