Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

Commit

Permalink
Version 0.5.4
Browse files Browse the repository at this point in the history
See PR #158
  • Loading branch information
RiccardoM committed Oct 14, 2020
1 parent 79ea10d commit 0be36ff
Show file tree
Hide file tree
Showing 16 changed files with 69 additions and 100 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,11 @@
# Version 0.5.4
## Bug fixes
- Fixed posts duplication

# Version 0.5.3
## Bug fixes
- Fixed a bug when creating a poll

# Version 0.5.2
## Bug fixes
- Fixed a bug when creating a post
Expand Down
5 changes: 5 additions & 0 deletions lib/entities/posts/polls/poll_answer.dart
Expand Up @@ -46,4 +46,9 @@ class PollAnswer extends Equatable {
List<Object> get props {
return [answer, user.address];
}

@override
String toString() {
return 'PollAnswer { answer: $answer, user: ${user.address} }';
}
}
5 changes: 5 additions & 0 deletions lib/entities/posts/polls/poll_option.dart
Expand Up @@ -48,4 +48,9 @@ class PollOption extends Equatable {
List<Object> get props {
return [id, text];
}

@override
String toString() {
return 'PollOption { id: $id, text: $text }';
}
}
14 changes: 1 addition & 13 deletions lib/entities/posts/polls/post_poll.dart
@@ -1,6 +1,3 @@
import 'dart:convert';

import 'package:crypto/crypto.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
Expand Down Expand Up @@ -88,20 +85,11 @@ class PostPoll extends Equatable {
options?.isNotEmpty == true;
}

/// Returns `true` is the poll is open considering the current time,
/// or `false` otherwise.
/// Tells if the poll is still open or not based on the current date time.
bool get isOpen {
return DateTime.now().isBefore(endDateTime);
}

/// Returns the SHA-256 of all the posts contents as a JSON object.
/// Some contents are excluded, such as the user answers.
String hashContents() {
final json = toJson();
json.remove('user_answers');
return sha256.convert(utf8.encode(jsonEncode(json))).toString();
}

/// Returns the JSON representation of this post poll as a [Map].
Map<String, dynamic> toJson() {
return _$PostPollToJson(this);
Expand Down
58 changes: 9 additions & 49 deletions lib/entities/posts/post.dart
@@ -1,7 +1,4 @@
import 'dart:convert';

import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart';
import 'package:equatable/equatable.dart';
import 'package:intl/intl.dart';
import 'package:json_annotation/json_annotation.dart';
Expand Down Expand Up @@ -32,8 +29,6 @@ class Post extends Equatable implements Comparable<Post> {
/// Identifier used to reference the post creation date.
static const DATE_FIELD = 'created';

static const LAST_EDITED_FIELD = 'last_edited';

/// Identifier used to reference post ids.
static const ID_FIELD = 'id';

Expand All @@ -43,15 +38,7 @@ class Post extends Equatable implements Comparable<Post> {
/// Identifier used to reference the user field.
static const OWNER_FIELD = 'user';

static const LINK_PREVIEW_FIELD = 'link_preview';

static const REACTIONS_FIELD = 'reactions';

static const MEDIA_FIELD = 'media';

static const POLL_FIELD = 'poll';

static const COMMENTS_FIELD = 'children';
static const LOCAL_ID_KEY = 'local_id';

/// Returns the current date and time in UTC time zone, formatted as
/// it should be to be used as a post creation date or last edit date.
Expand All @@ -73,7 +60,7 @@ class Post extends Equatable implements Comparable<Post> {
@JsonKey(name: DATE_FIELD)
final String created;

@JsonKey(name: LAST_EDITED_FIELD)
@JsonKey(name: 'last_edited')
final String lastEdited;

@JsonKey(name: 'allows_comments')
Expand All @@ -88,16 +75,16 @@ class Post extends Equatable implements Comparable<Post> {
@JsonKey(name: 'optional_data', defaultValue: {})
final Map<String, String> optionalData;

@JsonKey(name: MEDIA_FIELD, defaultValue: [])
@JsonKey(name: 'media', defaultValue: [])
final List<PostMedia> medias;

@JsonKey(name: POLL_FIELD, nullable: true)
@JsonKey(name: 'poll', nullable: true)
final PostPoll poll;

@JsonKey(name: REACTIONS_FIELD, defaultValue: [])
@JsonKey(name: 'reactions', defaultValue: [])
final List<Reaction> reactions;

@JsonKey(name: COMMENTS_FIELD, defaultValue: [])
@JsonKey(name: 'children', defaultValue: [])
final List<String> commentsIds;

/// Tells if the post has been synced with the blockchain or not
Expand All @@ -106,23 +93,21 @@ class Post extends Equatable implements Comparable<Post> {

/// Static method used to implement a custom deserialization of posts.
static PostStatus _postStatusFromJson(Map<String, dynamic> json) {
return json == null
? PostStatus(value: PostStatusValue.TX_SUCCESSFULL)
: PostStatus.fromJson(json);
return json == null ? PostStatus.txSuccessful() : PostStatus.fromJson(json);
}

/// Tells whether or not the post has been hidden from the user.
@JsonKey(name: HIDDEN_FIELD, defaultValue: false)
final bool hidden;

/// Represents the link preview associated to this post
@JsonKey(name: LINK_PREVIEW_FIELD, nullable: true)
@JsonKey(name: 'link_preview', nullable: true)
final RichLinkPreview linkPreview;

Post({
@required this.id,
this.parentId = '',
this.message,
@required this.message,
@required this.created,
this.lastEdited,
this.allowsComments = false,
Expand Down Expand Up @@ -178,31 +163,6 @@ class Post extends Equatable implements Comparable<Post> {
[];
}

/// Returns the SHA-256 of all the posts contents as a JSON object.
/// Some contents are excluded. Such as:
/// - the date
/// - the id
/// - the status
/// - the link preview
/// - the reactions
/// - the comments
String hashContents() {
final json = toJson();
json.remove(DATE_FIELD);
json.remove(LAST_EDITED_FIELD);
json.remove(ID_FIELD);
json.remove(STATUS_FIELD);
json.remove(LINK_PREVIEW_FIELD);
json.remove(REACTIONS_FIELD);
json.remove(COMMENTS_FIELD);
json.remove(MEDIA_FIELD);

json.remove(POLL_FIELD);
json['poll_data'] = poll?.hashContents();

return sha256.convert(utf8.encode(jsonEncode(json))).toString();
}

/// Returns a new [Post] having the same data as `this` one, but
/// with the specified data replaced.
Post copyWith({
Expand Down
24 changes: 20 additions & 4 deletions lib/entities/posts/post_status.dart
Expand Up @@ -19,11 +19,27 @@ class PostStatus extends Equatable {
this.data,
}) : assert(value != null);

/// Builds a [PostStatus] having as value [PostStatusValue.STORED_LOCALLY]
/// and as data the given [address].
factory PostStatus.storedLocally(String address) {
return PostStatus(
value: PostStatusValue.STORED_LOCALLY,
data: address,
);
return PostStatus(value: PostStatusValue.STORED_LOCALLY, data: address);
}

/// Builds a new [PostStatus] with value [PostStatusValue.SENDING_TX].
factory PostStatus.sendingTx() {
return PostStatus(value: PostStatusValue.SENDING_TX);
}

factory PostStatus.txSent(String txHash) {
return PostStatus(value: PostStatusValue.TX_SENT, data: txHash);
}

factory PostStatus.txSuccessful({String txHash}) {
return PostStatus(value: PostStatusValue.TX_SUCCESSFULL, data: txHash);
}

factory PostStatus.errored(String error) {
return PostStatus(value: PostStatusValue.ERRORED, data: error);
}

/// Returns true if the status contains an error message.
Expand Down
4 changes: 2 additions & 2 deletions lib/main.dart
Expand Up @@ -80,9 +80,9 @@ Future _setupDependencyInjection() async {
),
postsDatabase: await factory.openDatabase(
'posts.db',
version: 4,
version: 6,
onVersionChanged: (db, oldVersion, newVersion) async {
if (oldVersion < 4) {
if (oldVersion < 6) {
await deletePosts(db);
}
},
Expand Down
21 changes: 8 additions & 13 deletions lib/repositories/posts/posts_repository_impl.dart
Expand Up @@ -110,16 +110,10 @@ class PostsRepositoryImpl extends PostsRepository {
PostStatus postStatus;
switch (result.success) {
case true:
postStatus = PostStatus(
value: PostStatusValue.TX_SENT,
data: result.hash,
);
postStatus = PostStatus.txSent(result.hash);
break;
case false:
postStatus = PostStatus(
value: PostStatusValue.ERRORED,
data: result.error.errorMessage,
);
postStatus = PostStatus.errored(result.error.errorMessage);
break;
}

Expand All @@ -136,9 +130,8 @@ class PostsRepositoryImpl extends PostsRepository {
}

// Set the posts as syncing
final syncingStatus = PostStatus(value: PostStatusValue.SENDING_TX);
final syncingPosts = posts.map((post) {
return post.copyWith(status: syncingStatus);
return post.copyWith(status: PostStatus.sendingTx());
}).toList();
await _localPostsSource.savePosts(syncingPosts);

Expand All @@ -151,10 +144,12 @@ class PostsRepositoryImpl extends PostsRepository {

// emit event that tx has been successfully added to the chain
if (status.value == PostStatusValue.TX_SENT) {
final currentTxAmount =
await _localSettingsSource.get(SettingKeys.TX_AMOUNT) ?? 0;
final key = SettingKeys.TX_AMOUNT;
final currentTxAmount = await _localSettingsSource.get(key) ?? 0;
await _localSettingsSource.save(
SettingKeys.TX_AMOUNT, currentTxAmount + updatedPosts.length);
key,
currentTxAmount + updatedPosts.length,
);
}
}

Expand Down
5 changes: 0 additions & 5 deletions lib/sources/chain/models/msgs/chain_poll_data.dart
Expand Up @@ -16,9 +16,6 @@ class ChainPollData {
@JsonKey(name: 'end_date')
final String endDate;

@JsonKey(name: 'is_open')
final bool isOpen;

@JsonKey(name: 'allows_multiple_answers')
final bool allowsMultipleAnswers;

Expand All @@ -32,13 +29,11 @@ class ChainPollData {
@required this.question,
@required this.endDate,
@required this.options,
@required this.isOpen,
@required this.allowsMultipleAnswers,
@required this.allowsAnswerEdits,
}) : assert(question != null),
assert(endDate != null),
assert(options != null),
assert(isOpen != null),
assert(allowsMultipleAnswers != null),
assert(allowsAnswerEdits != null);

Expand Down
2 changes: 0 additions & 2 deletions lib/sources/chain/models/msgs/chain_poll_data.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion lib/sources/posts/local/local_posts_source.dart
Expand Up @@ -33,7 +33,10 @@ class LocalPostsSourceImpl implements LocalPostsSource {
/// given [post].
@visibleForTesting
String getPostKey(Post post) {
return post.hashContents();
if (post.optionalData.containsKey(Post.LOCAL_ID_KEY)) {
return post.optionalData[Post.LOCAL_ID_KEY];
}
return post.id;
}

/// Returns a [Filter] that allows to filter out all the posts that are
Expand Down
Expand Up @@ -23,7 +23,6 @@ class PostsMsgConverter {
return ChainPollData(
question: poll.question,
endDate: poll.endDate,
isOpen: true,
allowsMultipleAnswers: poll.allowsMultipleAnswers,
allowsAnswerEdits: poll.allowsAnswerEdits,
options: poll.options.map((e) {
Expand Down
10 changes: 2 additions & 8 deletions lib/ui/blocs/posts_list/posts_list_bloc.dart
Expand Up @@ -442,20 +442,14 @@ class PostsListBloc extends Bloc<PostsListEvent, PostsListState> {
/// Handles the event that tells the Bloc that a transaction has
/// been successful.
void _handleTxSuccessfulEvent(TxSuccessful event) async {
final status = PostStatus(
value: PostStatusValue.TX_SUCCESSFULL,
data: event.txHash,
);
final status = PostStatus.txSuccessful(txHash: event.txHash);
await _updatePostsStatusUseCase.update(event.txHash, status);
}

/// Handles the event that tells the Bloc that a transaction has not
/// been successful.
void _handleTxFailedEvent(TxFailed event) async {
final status = PostStatus(
value: PostStatusValue.ERRORED,
data: event.error,
);
final status = PostStatus.errored(event.error);
await _updatePostsStatusUseCase.update(event.txHash, status);
}

Expand Down
Expand Up @@ -193,7 +193,7 @@ class PostInputBloc extends Bloc<PostInputEvent, PostInputState> {
final post = await _createPostUseCase.create(
// If the post has a poll, the entered message should
// be the poll question instead
message: state.hasPoll ? null : state.message,
message: state.hasPoll ? '' : state.message,
allowsComments: state.allowsComments,
parentId: state.parentPost?.id,
medias: state.medias,
Expand Down
3 changes: 3 additions & 0 deletions lib/usecases/posts/usecase_create_post.dart
Expand Up @@ -33,6 +33,9 @@ class CreatePostUseCase {
subspace: Constants.SUBSPACE,
owner: account.toUser(),
status: PostStatus.storedLocally(account.address),
optionalData: {
Post.LOCAL_ID_KEY: date,
},
);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,6 +1,6 @@
name: mooncake
description: A decentralized microblogging application based on Desmos
version: 0.5.2+05200
version: 0.5.4+05400

environment:
sdk: ">=2.9.0 <3.0.0"
Expand Down

0 comments on commit 0be36ff

Please sign in to comment.