Skip to content

Commit

Permalink
feat: show status publish time on feed
Browse files Browse the repository at this point in the history
  • Loading branch information
aitorres committed Jan 6, 2025
1 parent 1060229 commit be11d57
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 6 deletions.
13 changes: 13 additions & 0 deletions lib/data/status.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import 'dart:ui';

import 'package:feathr/data/account.dart';
import 'package:relative_time/relative_time.dart';

/// The [Status] class represents information for a given status (toot)
/// made in a Mastodon instance.
Expand All @@ -9,6 +12,9 @@ class Status {
/// ID of the status in the Mastodon instance it belongs to
final String id;

/// Datetime when the status was created
final DateTime createdAt;

/// Main content of the status, in HTML format
final String content;

Expand All @@ -29,6 +35,7 @@ class Status {

Status({
required this.id,
required this.createdAt,
required this.content,
required this.account,
required this.favorited,
Expand All @@ -42,6 +49,7 @@ class Status {
factory Status.fromJson(Map<String, dynamic> data) {
return Status(
id: data["id"]!,
createdAt: DateTime.parse(data["created_at"]!),
content: data["content"]!,
account: Account.fromJson(data["account"]!),
favorited: data["favourited"]!,
Expand All @@ -58,4 +66,9 @@ class Status {
}
return content;
}

String getRelativeDate() {
// TODO: set up localization for the app
return createdAt.relativeTimeLocale(const Locale('en'));
}
}
4 changes: 4 additions & 0 deletions lib/widgets/status_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ class _StatusCardState extends State<StatusCard> {
status.account.acct,
style: TextStyle(color: Colors.white.withValues(alpha: 0.6)),
),
trailing: Text(
status.getRelativeDate(),
style: TextStyle(color: Colors.white.withValues(alpha: 0.6)),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
Expand Down
21 changes: 21 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.0"
flutter_localizations:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_secure_storage:
dependency: "direct main"
description:
Expand Down Expand Up @@ -429,6 +434,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.0"
intl:
dependency: transitive
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev"
source: hosted
version: "0.19.0"
io:
dependency: transitive
description:
Expand Down Expand Up @@ -701,6 +714,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.1"
relative_time:
dependency: "direct main"
description:
name: relative_time
sha256: "4e6c3b27d98ff6af5061b6dbaca178b5aa2607b7a7c2a77e6cae1d32b2759893"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
shelf:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ dependencies:

# Form validations
validators: ^3.0.0
relative_time: ^5.0.0

dev_dependencies:
flutter_test:
Expand Down
5 changes: 5 additions & 0 deletions test/data_test/status_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ void main() {
const Map<String, dynamic> testStatusNoReblog = {
"id": "11223344",
"content": "<p>I am a toot!</p>",
"created_at": "2025-01-01T00:00:00Z",
"favourited": true,
"bookmarked": false,
"reblogged": true,
Expand All @@ -25,6 +26,7 @@ void main() {
const Map<String, dynamic> testStatusWithReblog = {
"id": "11223344",
"content": "<p>I am a toot!</p>",
"created_at": "2025-01-01T00:00:00Z",
"favourited": true,
"bookmarked": false,
"reblogged": true,
Expand All @@ -41,6 +43,7 @@ void main() {
"reblog": {
"id": "55667788",
"content": "<p>I am an internal toot!</p>",
"created_at": "2025-01-01T00:00:00Z",
"favourited": false,
"bookmarked": true,
"reblogged": false,
Expand All @@ -64,6 +67,7 @@ void main() {

expect(status.id, equals("11223344"));
expect(status.content, equals("<p>I am a toot!</p>"));
expect(status.createdAt, equals(DateTime.parse("2025-01-01T00:00:00Z")));
expect(status.favorited, isTrue);
expect(status.bookmarked, isFalse);
expect(status.reblogged, isTrue);
Expand All @@ -84,6 +88,7 @@ void main() {
final status = Status.fromJson(testStatusWithReblog);
expect(status.id, equals("11223344"));
expect(status.content, equals("<p>I am a toot!</p>"));
expect(status.createdAt, equals(DateTime.parse("2025-01-01T00:00:00Z")));
expect(status.favorited, isTrue);
expect(status.bookmarked, isFalse);
expect(status.reblogged, isTrue);
Expand Down
12 changes: 6 additions & 6 deletions test/services_test/api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void main() {
httpClient: mockClient))
.thenAnswer(
(_) async => http.Response(
'{"id":"$testStatusId","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":false,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
'{"id":"$testStatusId","created_at": "2025-01-01T00:00:00Z","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":false,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
200,
),
);
Expand Down Expand Up @@ -181,7 +181,7 @@ void main() {
httpClient: mockClient))
.thenAnswer(
(_) async => http.Response(
'{"id":"$testStatusId","content":"<p>I am a toot!</p>","favourited":false,"bookmarked":false,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
'{"id":"$testStatusId","created_at": "2025-01-01T00:00:00Z","content":"<p>I am a toot!</p>","favourited":false,"bookmarked":false,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
200,
),
);
Expand Down Expand Up @@ -248,7 +248,7 @@ void main() {
httpClient: mockClient))
.thenAnswer(
(_) async => http.Response(
'{"id":"$testStatusId","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":true,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
'{"id":"$testStatusId","created_at": "2025-01-01T00:00:00Z","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":true,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
200,
),
);
Expand Down Expand Up @@ -315,7 +315,7 @@ void main() {
httpClient: mockClient))
.thenAnswer(
(_) async => http.Response(
'{"id":"$testStatusId","content":"<p>I am a toot!</p>","favourited":false,"bookmarked":false,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
'{"id":"$testStatusId","created_at": "2025-01-01T00:00:00Z","content":"<p>I am a toot!</p>","favourited":false,"bookmarked":false,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}',
200,
),
);
Expand Down Expand Up @@ -379,7 +379,7 @@ void main() {
httpClient: mockClient))
.thenAnswer(
(_) async => http.Response(
'{"reblog":{"id":"$testStatusId","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":true,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}}',
'{"reblog":{"id":"$testStatusId","created_at": "2025-01-01T00:00:00Z","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":true,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}}',
200,
),
);
Expand Down Expand Up @@ -446,7 +446,7 @@ void main() {
httpClient: mockClient))
.thenAnswer(
(_) async => http.Response(
'{"reblog":{"id":"$testStatusId","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":true,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}}',
'{"reblog":{"id":"$testStatusId","created_at": "2025-01-01T00:00:00Z","content":"<p>I am a toot!</p>","favourited":true,"bookmarked":true,"reblogged":true,"account":{"id":"this is an id","username":"username123","acct":"username123","display_name":"user display name","locked":false,"bot":true,"avatar":"avatar-url","header":"header-url"}}}',
200,
),
);
Expand Down
1 change: 1 addition & 0 deletions test/widgets_test/status_card_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void main() {
ApiService apiService = getTestApiService();
Status status = Status(
id: "12345678",
createdAt: DateTime(2025, 1, 5, 14, 30, 0),
content: "<p>This is a toot!</p>",
account: apiService.currentAccount!,
favorited: true,
Expand Down

0 comments on commit be11d57

Please sign in to comment.