kopia lustrzana https://gitlab.com/mysocialportal/relatica
Add Visibility object concept throughout, including image displays
rodzic
a7f3bb26ad
commit
aafe6dea7c
|
@ -42,8 +42,6 @@ class _StatusControlState extends State<FlattenedTreeEntryControl> {
|
|||
|
||||
TimelineEntry get entry => item.timelineEntry;
|
||||
|
||||
bool get isPublic => entry.isPublic;
|
||||
|
||||
bool get isPost => entry.parentId.isEmpty;
|
||||
|
||||
bool get hasComments => entry.engagementSummary.repliesCount > 0;
|
||||
|
|
|
@ -44,8 +44,6 @@ class _PostControlState extends State<PostControl> {
|
|||
|
||||
TimelineEntry get entry => item.entry;
|
||||
|
||||
bool get isPublic => item.entry.isPublic;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:logging/logging.dart';
|
|||
import '../../globals.dart';
|
||||
import '../../models/connection.dart';
|
||||
import '../../models/timeline_entry.dart';
|
||||
import '../../models/visibility.dart';
|
||||
import '../../routes.dart';
|
||||
import '../../services/connections_manager.dart';
|
||||
import '../../utils/active_profile_selector.dart';
|
||||
|
@ -106,7 +107,9 @@ class StatusHeaderControl extends StatelessWidget {
|
|||
),
|
||||
const HorizontalPadding(),
|
||||
Icon(
|
||||
entry.isPublic ? Icons.public : Icons.lock,
|
||||
entry.visibility.type == VisibilityType.public
|
||||
? Icons.public
|
||||
: Icons.lock,
|
||||
color: Theme.of(context).hintColor,
|
||||
size: Theme.of(context).textTheme.caption?.fontSize,
|
||||
),
|
||||
|
|
|
@ -651,6 +651,7 @@ class StatusesClient extends FriendicaClient {
|
|||
if (spoilerText.isNotEmpty) 'spoiler_text': spoilerText,
|
||||
if (inReplyToId.isNotEmpty) 'in_reply_to_id': inReplyToId,
|
||||
if (mediaIds.isNotEmpty) 'media_ids': mediaIds,
|
||||
'visibility': 'unlisted',
|
||||
'friendica': {
|
||||
'title': '',
|
||||
},
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'visibility.dart';
|
||||
|
||||
class ImageEntry {
|
||||
final String id;
|
||||
final String album;
|
||||
|
@ -7,18 +9,21 @@ class ImageEntry {
|
|||
final DateTime created;
|
||||
final int height;
|
||||
final int width;
|
||||
final Visibility visibility;
|
||||
final List<ImageEntryScale> scales;
|
||||
|
||||
ImageEntry(
|
||||
{required this.id,
|
||||
required this.album,
|
||||
required this.filename,
|
||||
required this.description,
|
||||
required this.thumbnailUrl,
|
||||
required this.created,
|
||||
required this.height,
|
||||
required this.width,
|
||||
required this.scales});
|
||||
ImageEntry({
|
||||
required this.id,
|
||||
required this.album,
|
||||
required this.filename,
|
||||
required this.description,
|
||||
required this.thumbnailUrl,
|
||||
required this.created,
|
||||
required this.height,
|
||||
required this.width,
|
||||
required this.visibility,
|
||||
required this.scales,
|
||||
});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import 'package:path/path.dart' as p;
|
||||
import 'package:relatica/models/image_entry.dart';
|
||||
|
||||
import '../globals.dart';
|
||||
import 'attachment_media_type_enum.dart';
|
||||
import 'image_entry.dart';
|
||||
import 'visibility.dart';
|
||||
|
||||
class MediaAttachment {
|
||||
static final _graphicsExtensions = ['jpg', 'png', 'gif', 'tif'];
|
||||
|
@ -26,16 +27,20 @@ class MediaAttachment {
|
|||
|
||||
final String description;
|
||||
|
||||
MediaAttachment(
|
||||
{required this.id,
|
||||
required this.uri,
|
||||
required this.creationTimestamp,
|
||||
required this.metadata,
|
||||
required this.thumbnailUri,
|
||||
required this.fullFileUri,
|
||||
required this.title,
|
||||
required this.explicitType,
|
||||
required this.description});
|
||||
final Visibility visibility;
|
||||
|
||||
MediaAttachment({
|
||||
required this.id,
|
||||
required this.uri,
|
||||
required this.creationTimestamp,
|
||||
required this.metadata,
|
||||
required this.thumbnailUri,
|
||||
required this.fullFileUri,
|
||||
required this.title,
|
||||
required this.explicitType,
|
||||
required this.description,
|
||||
required this.visibility,
|
||||
});
|
||||
|
||||
MediaAttachment.randomBuilt()
|
||||
: id = randomId(),
|
||||
|
@ -46,7 +51,11 @@ class MediaAttachment {
|
|||
thumbnailUri = Uri.parse('${randomId()}.jpg'),
|
||||
description = 'Random description ${randomId()}',
|
||||
explicitType = AttachmentMediaType.image,
|
||||
metadata = {'value1': randomId(), 'value2': randomId()};
|
||||
metadata = {
|
||||
'value1': randomId(),
|
||||
'value2': randomId(),
|
||||
},
|
||||
visibility = Visibility.public();
|
||||
|
||||
MediaAttachment.blank()
|
||||
: id = '',
|
||||
|
@ -57,19 +66,8 @@ class MediaAttachment {
|
|||
title = '',
|
||||
fullFileUri = Uri(),
|
||||
description = '',
|
||||
metadata = {};
|
||||
|
||||
factory MediaAttachment.fromMastodonJson(Map<String, dynamic> json) =>
|
||||
MediaAttachment(
|
||||
id: json['id'] ?? '',
|
||||
uri: Uri.parse(json['url'] ?? 'http://localhost'),
|
||||
creationTimestamp: 0,
|
||||
metadata: {},
|
||||
thumbnailUri: Uri.parse(json['url'] ?? 'http://localhost'),
|
||||
title: '',
|
||||
fullFileUri: Uri.parse(json['remote_url'] ?? 'http://localhost'),
|
||||
explicitType: AttachmentMediaType.parse(json['type']),
|
||||
description: json['description'] ?? '');
|
||||
metadata = {},
|
||||
visibility = Visibility.public();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -86,6 +84,7 @@ class MediaAttachment {
|
|||
created: DateTime.fromMillisecondsSinceEpoch(creationTimestamp),
|
||||
height: 0,
|
||||
width: 0,
|
||||
visibility: visibility,
|
||||
scales: []);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'link_data.dart';
|
|||
import 'link_preview_data.dart';
|
||||
import 'location_data.dart';
|
||||
import 'media_attachment.dart';
|
||||
import 'visibility.dart';
|
||||
|
||||
class TimelineEntry {
|
||||
final String id;
|
||||
|
@ -33,7 +34,7 @@ class TimelineEntry {
|
|||
|
||||
final bool youReshared;
|
||||
|
||||
final bool isPublic;
|
||||
final Visibility visibility;
|
||||
|
||||
final String author;
|
||||
|
||||
|
@ -64,7 +65,7 @@ class TimelineEntry {
|
|||
this.backdatedTimestamp = 0,
|
||||
this.modificationTimestamp = 0,
|
||||
this.youReshared = false,
|
||||
this.isPublic = true,
|
||||
Visibility? visibility,
|
||||
this.body = '',
|
||||
this.title = '',
|
||||
this.spoilerText = '',
|
||||
|
@ -82,7 +83,8 @@ class TimelineEntry {
|
|||
this.dislikes = const [],
|
||||
this.mediaAttachments = const [],
|
||||
this.engagementSummary = const EngagementSummary(),
|
||||
this.linkPreviewData});
|
||||
this.linkPreviewData})
|
||||
: visibility = visibility ?? Visibility.public();
|
||||
|
||||
TimelineEntry.randomBuilt()
|
||||
: creationTimestamp = DateTime.now().millisecondsSinceEpoch,
|
||||
|
@ -90,7 +92,9 @@ class TimelineEntry {
|
|||
modificationTimestamp = DateTime.now().millisecondsSinceEpoch,
|
||||
id = randomId(),
|
||||
youReshared = DateTime.now().second ~/ 2 == 0 ? true : false,
|
||||
isPublic = DateTime.now().second ~/ 2 == 0 ? true : false,
|
||||
visibility = DateTime.now().second ~/ 2 == 0
|
||||
? Visibility.public()
|
||||
: Visibility.private(),
|
||||
parentId = randomId(),
|
||||
externalLink = 'Random external link ${randomId()}',
|
||||
body = 'Random post text ${randomId()}',
|
||||
|
@ -116,7 +120,7 @@ class TimelineEntry {
|
|||
int? backdatedTimestamp,
|
||||
int? modificationTimestamp,
|
||||
bool? isReshare,
|
||||
bool? isPublic,
|
||||
Visibility? visibility,
|
||||
String? id,
|
||||
String? parentId,
|
||||
String? externalLink,
|
||||
|
@ -145,7 +149,7 @@ class TimelineEntry {
|
|||
modificationTimestamp ?? this.modificationTimestamp,
|
||||
id: id ?? this.id,
|
||||
youReshared: isReshare ?? this.youReshared,
|
||||
isPublic: isPublic ?? this.isPublic,
|
||||
visibility: visibility ?? this.visibility,
|
||||
parentId: parentId ?? this.parentId,
|
||||
externalLink: externalLink ?? this.externalLink,
|
||||
body: body ?? this.body,
|
||||
|
@ -195,7 +199,7 @@ class TimelineEntry {
|
|||
title == other.title &&
|
||||
spoilerText == other.spoilerText &&
|
||||
youReshared == other.youReshared &&
|
||||
isPublic == other.isPublic &&
|
||||
visibility == other.visibility &&
|
||||
author == other.author &&
|
||||
authorId == other.authorId &&
|
||||
externalLink == other.externalLink &&
|
||||
|
@ -222,7 +226,7 @@ class TimelineEntry {
|
|||
title.hashCode ^
|
||||
spoilerText.hashCode ^
|
||||
youReshared.hashCode ^
|
||||
isPublic.hashCode ^
|
||||
visibility.hashCode ^
|
||||
author.hashCode ^
|
||||
authorId.hashCode ^
|
||||
externalLink.hashCode ^
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
enum VisibilityType {
|
||||
public,
|
||||
private,
|
||||
}
|
||||
|
||||
class Visibility {
|
||||
final VisibilityType type;
|
||||
|
||||
final List<String> allowedUserIds;
|
||||
|
||||
final List<String> excludedUserIds;
|
||||
|
||||
final List<String> allowedGroupIds;
|
||||
|
||||
final List<String> excludedGroupIds;
|
||||
|
||||
bool get hasDetails =>
|
||||
allowedUserIds.isNotEmpty ||
|
||||
excludedUserIds.isNotEmpty ||
|
||||
allowedGroupIds.isNotEmpty ||
|
||||
excludedGroupIds.isNotEmpty;
|
||||
|
||||
const Visibility({
|
||||
required this.type,
|
||||
this.allowedUserIds = const [],
|
||||
this.excludedUserIds = const [],
|
||||
this.allowedGroupIds = const [],
|
||||
this.excludedGroupIds = const [],
|
||||
});
|
||||
|
||||
factory Visibility.public() => const Visibility(
|
||||
type: VisibilityType.public,
|
||||
);
|
||||
|
||||
factory Visibility.private() => const Visibility(
|
||||
type: VisibilityType.private,
|
||||
);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is Visibility &&
|
||||
runtimeType == other.runtimeType &&
|
||||
type == other.type &&
|
||||
allowedUserIds == other.allowedUserIds &&
|
||||
excludedUserIds == other.excludedUserIds &&
|
||||
allowedGroupIds == other.allowedGroupIds &&
|
||||
excludedGroupIds == other.excludedGroupIds;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
type.hashCode ^
|
||||
allowedUserIds.hashCode ^
|
||||
excludedUserIds.hashCode ^
|
||||
allowedGroupIds.hashCode ^
|
||||
excludedGroupIds.hashCode;
|
||||
}
|
|
@ -6,6 +6,7 @@ import '../controls/login_aware_cached_network_image.dart';
|
|||
import '../controls/standard_appbar.dart';
|
||||
import '../controls/status_and_refresh_button.dart';
|
||||
import '../globals.dart';
|
||||
import '../models/visibility.dart';
|
||||
import '../serializers/friendica/image_entry_friendica_extensions.dart';
|
||||
import '../services/gallery_service.dart';
|
||||
import '../services/network_status_service.dart';
|
||||
|
@ -122,10 +123,23 @@ class GalleryScreen extends StatelessWidget {
|
|||
);
|
||||
}));
|
||||
},
|
||||
child: LoginAwareCachedNetworkImage(
|
||||
width: thumbnailDimension,
|
||||
height: thumbnailDimension,
|
||||
imageUrl: image.thumbnailUrl,
|
||||
child: Card(
|
||||
child: Stack(
|
||||
children: [
|
||||
LoginAwareCachedNetworkImage(
|
||||
width: thumbnailDimension,
|
||||
height: thumbnailDimension,
|
||||
imageUrl: image.thumbnailUrl,
|
||||
),
|
||||
Positioned(
|
||||
bottom: 5.0,
|
||||
right: 5.0,
|
||||
child: Icon(image.visibility.type == VisibilityType.public
|
||||
? Icons.public
|
||||
: Icons.lock),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import '../../models/attachment_media_type_enum.dart';
|
||||
import '../../models/image_entry.dart';
|
||||
import '../../models/media_attachment.dart';
|
||||
import 'visibility_friendica_extensions.dart';
|
||||
|
||||
extension ImageEntryFriendicaExtension on ImageEntry {
|
||||
static ImageEntry fromJson(Map<String, dynamic> json) => ImageEntry(
|
||||
|
@ -12,6 +13,7 @@ extension ImageEntryFriendicaExtension on ImageEntry {
|
|||
created: DateTime.tryParse(json['created']) ?? DateTime(0),
|
||||
height: json['height'],
|
||||
width: json['width'],
|
||||
visibility: VisibilityFriendicaExtensions.fromJson(json),
|
||||
scales: (json['scales'] as List<dynamic>? ?? [])
|
||||
.map((scaleJson) => _scaleFromJson(scaleJson))
|
||||
.toList());
|
||||
|
@ -30,14 +32,16 @@ extension ImageEntryFriendicaExtension on ImageEntry {
|
|||
final thumbUri = Uri.parse(thumbnailUrl);
|
||||
final fullFileUri = scales.first.link;
|
||||
return MediaAttachment(
|
||||
id: id,
|
||||
uri: fullFileUri,
|
||||
fullFileUri: fullFileUri,
|
||||
creationTimestamp: created.millisecondsSinceEpoch,
|
||||
metadata: {},
|
||||
thumbnailUri: thumbUri,
|
||||
title: filename,
|
||||
explicitType: AttachmentMediaType.image,
|
||||
description: description);
|
||||
id: id,
|
||||
uri: fullFileUri,
|
||||
fullFileUri: fullFileUri,
|
||||
creationTimestamp: created.millisecondsSinceEpoch,
|
||||
metadata: {},
|
||||
thumbnailUri: thumbUri,
|
||||
title: filename,
|
||||
explicitType: AttachmentMediaType.image,
|
||||
description: description,
|
||||
visibility: visibility,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import '../../models/attachment_media_type_enum.dart';
|
||||
import '../../models/media_attachment.dart';
|
||||
import '../../models/visibility.dart';
|
||||
|
||||
extension MediaAttachmentFriendicaExtensions on MediaAttachment {
|
||||
static MediaAttachment fromJson(Map<String, dynamic> json) {
|
||||
static MediaAttachment fromJson(
|
||||
Map<String, dynamic> json,
|
||||
Visibility visibility,
|
||||
) {
|
||||
final id = json['id'];
|
||||
final uri = Uri.parse(json['url']);
|
||||
const creationTimestamp = 0;
|
||||
|
@ -18,14 +22,16 @@ extension MediaAttachmentFriendicaExtensions on MediaAttachment {
|
|||
const description = '';
|
||||
|
||||
return MediaAttachment(
|
||||
id: id,
|
||||
uri: uri,
|
||||
fullFileUri: uri,
|
||||
creationTimestamp: creationTimestamp,
|
||||
metadata: metadata,
|
||||
thumbnailUri: thumbnailUri,
|
||||
title: title,
|
||||
explicitType: explicitType,
|
||||
description: description);
|
||||
id: id,
|
||||
uri: uri,
|
||||
fullFileUri: uri,
|
||||
creationTimestamp: creationTimestamp,
|
||||
metadata: metadata,
|
||||
thumbnailUri: thumbnailUri,
|
||||
title: title,
|
||||
explicitType: explicitType,
|
||||
description: description,
|
||||
visibility: visibility,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:logging/logging.dart';
|
|||
|
||||
import '../../models/location_data.dart';
|
||||
import '../../models/timeline_entry.dart';
|
||||
import '../../models/visibility.dart';
|
||||
import '../../utils/dateutils.dart';
|
||||
import 'connection_friendica_extensions.dart';
|
||||
import 'media_attachment_friendica_extensions.dart';
|
||||
|
@ -22,7 +23,8 @@ extension TimelineEntryFriendicaExtensions on TimelineEntry {
|
|||
: 0;
|
||||
final id = json['id_str'] ?? '';
|
||||
final isReshare = json.containsKey('retweeted_status');
|
||||
final isPublic = json['friendica_private'] == 'false';
|
||||
final isPublic = !(json['friendica_private'] ?? false);
|
||||
final visibility = isPublic ? Visibility.public() : Visibility.private();
|
||||
final parentId = json['in_reply_to_status_id_str'] ?? '';
|
||||
final parentAuthor = json['in_reply_to_screen_name'] ?? '';
|
||||
final parentAuthorId = json['in_reply_to_user_id_str'] ?? '';
|
||||
|
@ -35,7 +37,7 @@ extension TimelineEntryFriendicaExtensions on TimelineEntry {
|
|||
final modificationTimestamp = timestamp;
|
||||
final backdatedTimestamp = timestamp;
|
||||
final mediaAttachments = (json['attachments'] as List<dynamic>? ?? [])
|
||||
.map((j) => MediaAttachmentFriendicaExtensions.fromJson(j))
|
||||
.map((j) => MediaAttachmentFriendicaExtensions.fromJson(j, visibility))
|
||||
.toList();
|
||||
final likes =
|
||||
(json['friendica_activities']?['like'] as List<dynamic>? ?? [])
|
||||
|
@ -53,7 +55,7 @@ extension TimelineEntryFriendicaExtensions on TimelineEntry {
|
|||
locationData: actualLocationData,
|
||||
body: body,
|
||||
youReshared: isReshare,
|
||||
isPublic: isPublic,
|
||||
visibility: visibility,
|
||||
id: id,
|
||||
parentId: parentId,
|
||||
parentAuthorId: parentAuthorId,
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import '../../models/visibility.dart';
|
||||
|
||||
extension VisibilityFriendicaExtensions on Visibility {
|
||||
static Visibility fromJson(Map<String, dynamic> json) {
|
||||
final allowedUserIds = _parseAcl(json['allow_cid']);
|
||||
final excludedGroupIds = _parseAcl(json['deny_cid']);
|
||||
final allowedGroupIds = _parseAcl(json['allow_gid']);
|
||||
final excludedUserIds = _parseAcl(json['deny_cid']);
|
||||
final topLevelPrivate = json['friendica_private'];
|
||||
late final VisibilityType type;
|
||||
if (topLevelPrivate == null) {
|
||||
type = allowedUserIds.isEmpty &&
|
||||
excludedUserIds.isEmpty &&
|
||||
allowedGroupIds.isEmpty &&
|
||||
excludedGroupIds.isEmpty
|
||||
? VisibilityType.public
|
||||
: VisibilityType.private;
|
||||
} else {
|
||||
type = topLevelPrivate ? VisibilityType.public : VisibilityType.private;
|
||||
}
|
||||
|
||||
return Visibility(
|
||||
type: type,
|
||||
allowedUserIds: allowedUserIds,
|
||||
excludedUserIds: excludedUserIds,
|
||||
allowedGroupIds: allowedGroupIds,
|
||||
excludedGroupIds: excludedGroupIds,
|
||||
);
|
||||
}
|
||||
|
||||
static List<String> _parseAcl(String? acl) =>
|
||||
acl?.split(RegExp('[><]')).where((e) => e.isNotEmpty).toList() ?? [];
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import '../../models/attachment_media_type_enum.dart';
|
||||
import '../../models/media_attachment.dart';
|
||||
import '../../models/visibility.dart';
|
||||
|
||||
extension MediaAttachmentMastodonExtension on MediaAttachment {
|
||||
static MediaAttachment fromJson(
|
||||
Map<String, dynamic> json, Visibility visibility) {
|
||||
return MediaAttachment(
|
||||
id: json['id'] ?? '',
|
||||
uri: Uri.parse(json['url'] ?? 'http://localhost'),
|
||||
creationTimestamp: 0,
|
||||
metadata: {},
|
||||
thumbnailUri: Uri.parse(json['url'] ?? 'http://localhost'),
|
||||
title: '',
|
||||
fullFileUri: Uri.parse(json['remote_url'] ?? 'http://localhost'),
|
||||
explicitType: AttachmentMediaType.parse(json['type']),
|
||||
description: json['description'] ?? '',
|
||||
visibility: visibility);
|
||||
}
|
||||
}
|
|
@ -4,8 +4,8 @@ import '../../globals.dart';
|
|||
import '../../models/engagement_summary.dart';
|
||||
import '../../models/link_data.dart';
|
||||
import '../../models/location_data.dart';
|
||||
import '../../models/media_attachment.dart';
|
||||
import '../../models/timeline_entry.dart';
|
||||
import '../../models/visibility.dart';
|
||||
import '../../services/connections_manager.dart';
|
||||
import '../../services/hashtag_service.dart';
|
||||
import '../../utils/active_profile_selector.dart';
|
||||
|
@ -13,6 +13,7 @@ import '../../utils/dateutils.dart';
|
|||
import 'connection_mastodon_extensions.dart';
|
||||
import 'hashtag_mastodon_extensions.dart';
|
||||
import 'link_preview_mastodon_extensions.dart';
|
||||
import 'media_attachment_mastodon_extension.dart';
|
||||
|
||||
final _logger = Logger('TimelineEntryMastodonExtensions');
|
||||
|
||||
|
@ -29,7 +30,9 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
|
|||
: 0;
|
||||
final id = json['id'] ?? '';
|
||||
final youReshared = json['reblogged'] ?? false;
|
||||
final isPublic = json['visibility'] == 'public';
|
||||
final visibility = ['public', 'unlisted'].contains(json['visibility'])
|
||||
? Visibility.public()
|
||||
: Visibility.private();
|
||||
final parentId = json['in_reply_to_id'] ?? '';
|
||||
final parentAuthor = json['in_reply_to_account_id'] ?? '';
|
||||
final parentAuthorId = json['in_reply_to_account_id'] ?? '';
|
||||
|
@ -47,7 +50,8 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
|
|||
? <LinkData>[]
|
||||
: [LinkData.fromMastodonJson(json['card'])];
|
||||
final mediaAttachments = (json['media_attachments'] as List<dynamic>? ?? [])
|
||||
.map((json) => MediaAttachment.fromMastodonJson(json))
|
||||
.map((json) =>
|
||||
MediaAttachmentMastodonExtension.fromJson(json, visibility))
|
||||
.toList();
|
||||
final favoritesCount = json['favourites_count'] ?? 0;
|
||||
final repliesCount = json['replies_count'] ?? 0;
|
||||
|
@ -100,7 +104,7 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
|
|||
spoilerText: spoilerText,
|
||||
body: body,
|
||||
youReshared: youReshared,
|
||||
isPublic: isPublic,
|
||||
visibility: visibility,
|
||||
id: id,
|
||||
parentId: parentId,
|
||||
parentAuthorId: parentAuthorId,
|
||||
|
|
Ładowanie…
Reference in New Issue