Add network icon to timeline entry seeded from Application data

This commit is contained in:
Hank Grabowski 2024-06-20 16:07:00 -04:00
parent cba27ae21b
commit cb3c2d97b7
10 changed files with 261 additions and 51 deletions

3
devtools_options.yaml Normal file
View file

@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

Binary file not shown.

View file

@ -15,6 +15,7 @@ import '../../utils/dateutils.dart';
import '../image_control.dart';
import '../padding.dart';
import '../visibility_dialog.dart';
import 'timeline_network_info_control.dart';
class StatusHeaderControl extends StatelessWidget {
static final _logger = Logger('$StatusHeaderControl');
@ -135,6 +136,7 @@ class StatusHeaderControl extends StatelessWidget {
size: Theme.of(context).textTheme.bodySmall?.fontSize,
),
),
TimelineNetworkInfoControl(info: entry.networkInfo),
],
),
],

View file

@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import '../../globals.dart';
import '../../models/timeline_network_info.dart';
class TimelineNetworkInfoControl extends StatelessWidget {
final TimelineNetworkInfo info;
const TimelineNetworkInfoControl({super.key, required this.info});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () async => showConfirmDialog(context,
info.network == KnownNetworks.unknown ? info.name : info.labelName),
child: Text(
info.forkAwesomeUnicode,
style: const TextStyle(fontFamily: 'ForkAwesome'),
),
);
}
}
extension KnownNetworkExtensions on TimelineNetworkInfo {
String get labelName => switch (network) {
KnownNetworks.activityPub => 'ActivityPub',
KnownNetworks.bluesky => 'Bluesky',
KnownNetworks.calckey => 'Calckey',
KnownNetworks.diaspora => 'Diaspora',
KnownNetworks.drupal => 'Drupal',
KnownNetworks.firefish => 'Firefish',
KnownNetworks.friendica => 'Friendica',
KnownNetworks.funkwhale => 'Funkwhale',
KnownNetworks.gnu_social => 'GNU Social',
KnownNetworks.hubzilla => 'Hubzilla',
KnownNetworks.kbin => 'Kbin',
KnownNetworks.lemmy => 'Lemmy',
KnownNetworks.mastodon => 'Mastodon',
KnownNetworks.nextcloud => 'Nextcloud',
KnownNetworks.peertube => 'PeerTube',
KnownNetworks.pixelfed => 'Pixelfed',
KnownNetworks.pleroma => 'Pleroma',
KnownNetworks.plume => 'Plume',
KnownNetworks.red => 'Red',
KnownNetworks.redmatrix => 'RedMatrix',
KnownNetworks.socialhome => 'Socialhome',
KnownNetworks.threads => 'Threads',
KnownNetworks.wordpress => 'WordPress',
KnownNetworks.unknown => 'Unknown',
};
String get forkAwesomeUnicode => switch (network) {
KnownNetworks.activityPub => '\uf2f2',
KnownNetworks.bluesky => '\uf111',
KnownNetworks.calckey => '\uf1ec',
KnownNetworks.diaspora => '\uf2e5',
KnownNetworks.drupal => '\uf1a9',
KnownNetworks.firefish => '\uf06d',
KnownNetworks.friendica => '\uf2e6',
KnownNetworks.funkwhale => '\uf339',
KnownNetworks.gnu_social => '\uf2e7',
KnownNetworks.hubzilla => '\uf2eb',
KnownNetworks.kbin => '\uf058',
KnownNetworks.lemmy => '\uf0c0',
KnownNetworks.mastodon => '\uf2e1',
KnownNetworks.nextcloud => '\uf307',
KnownNetworks.peertube => '\uf2e4',
KnownNetworks.pixelfed => '\uf314',
KnownNetworks.pleroma => '\uf324',
KnownNetworks.plume => '\uf356',
KnownNetworks.red => '\uf2eb',
KnownNetworks.redmatrix => '\uf2eb',
KnownNetworks.socialhome => '\uf2ec',
KnownNetworks.threads => '\uf16d',
KnownNetworks.wordpress => '\uf19a',
KnownNetworks.unknown => '\uf059',
};
}

View file

@ -5,6 +5,7 @@ import 'link_data.dart';
import 'link_preview_data.dart';
import 'location_data.dart';
import 'media_attachment.dart';
import 'timeline_network_info.dart';
import 'visibility.dart';
class TimelineEntry {
@ -52,10 +53,12 @@ class TimelineEntry {
final List<MediaAttachment> mediaAttachments;
final EngagementSummary engagementSummary;
final TimelineNetworkInfo networkInfo;
final LinkPreviewData? linkPreviewData;
final EngagementSummary engagementSummary;
TimelineEntry(
{this.id = '',
this.parentId = '',
@ -80,6 +83,7 @@ class TimelineEntry {
this.dislikes = const [],
this.mediaAttachments = const [],
this.engagementSummary = const EngagementSummary(),
this.networkInfo = TimelineNetworkInfo.empty,
this.linkPreviewData})
: visibility = visibility ?? Visibility.public();
@ -108,6 +112,7 @@ class TimelineEntry {
likes = [],
dislikes = [],
mediaAttachments = [],
networkInfo = TimelineNetworkInfo.empty,
engagementSummary = const EngagementSummary(),
linkPreviewData = LinkPreviewData(link: 'fake link');
@ -138,6 +143,7 @@ class TimelineEntry {
List<Connection>? dislikes,
List<MediaAttachment>? mediaAttachments,
EngagementSummary? engagementSummary,
TimelineNetworkInfo? networkInfo,
LinkPreviewData? linkPreviewData,
}) {
return TimelineEntry(
@ -165,6 +171,7 @@ class TimelineEntry {
dislikes: dislikes ?? this.dislikes,
mediaAttachments: mediaAttachments ?? this.mediaAttachments,
engagementSummary: engagementSummary ?? this.engagementSummary,
networkInfo: networkInfo ?? this.networkInfo,
linkPreviewData: linkPreviewData ?? this.linkPreviewData,
);
}
@ -205,6 +212,7 @@ class TimelineEntry {
likes == other.likes &&
dislikes == other.dislikes &&
mediaAttachments == other.mediaAttachments &&
networkInfo == other.networkInfo &&
engagementSummary == other.engagementSummary;
@override
@ -231,5 +239,6 @@ class TimelineEntry {
likes.hashCode ^
dislikes.hashCode ^
mediaAttachments.hashCode ^
networkInfo.hashCode ^
engagementSummary.hashCode;
}

View file

@ -0,0 +1,56 @@
enum KnownNetworks {
activityPub,
bluesky,
calckey,
diaspora,
drupal,
firefish,
friendica,
funkwhale,
gnu_social,
hubzilla,
kbin,
lemmy,
mastodon,
nextcloud,
peertube,
pixelfed,
pleroma,
plume,
red,
redmatrix,
socialhome,
threads,
wordpress,
unknown,
}
class TimelineNetworkInfo {
static const empty = TimelineNetworkInfo(
name: 'Unknown',
vapidKey: '',
network: KnownNetworks.unknown,
);
final String name;
final String vapidKey;
final KnownNetworks network;
const TimelineNetworkInfo({
required this.name,
required this.vapidKey,
required this.network,
});
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is TimelineNetworkInfo &&
runtimeType == other.runtimeType &&
name == other.name &&
vapidKey == other.vapidKey &&
network == other.network;
@override
int get hashCode => name.hashCode ^ vapidKey.hashCode ^ network.hashCode;
}

View file

@ -5,6 +5,7 @@ import '../../models/engagement_summary.dart';
import '../../models/link_data.dart';
import '../../models/location_data.dart';
import '../../models/timeline_entry.dart';
import '../../models/timeline_network_info.dart';
import '../../models/visibility.dart';
import '../../services/auth_service.dart';
import '../../services/connections_manager.dart';
@ -17,6 +18,7 @@ import 'connection_mastodon_extensions.dart';
import 'hashtag_mastodon_extensions.dart';
import 'link_preview_mastodon_extensions.dart';
import 'media_attachment_mastodon_extension.dart';
import 'timeline_network_info_mastodon_extensions.dart';
final _logger = Logger('TimelineEntryMastodonExtensions');
@ -143,6 +145,10 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
final connection = ConnectionMastodonExtensions.fromJson(json['account']);
connectionManager?.upsertConnection(connection);
final networkInfo = json['application'] != null
? TimelineNetworkInfoMastodonExtensions.fromJson(json['application'])
: TimelineNetworkInfo.empty;
return TimelineEntry(
creationTimestamp: timestamp,
modificationTimestamp: modificationTimestamp,
@ -165,6 +171,7 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
tags: tags,
mediaAttachments: mediaAttachments,
engagementSummary: engagementSummary,
networkInfo: networkInfo,
linkPreviewData: linkPreviewData,
);
}

View file

@ -0,0 +1,74 @@
import '../../models/timeline_network_info.dart';
extension TimelineNetworkInfoMastodonExtensions on TimelineNetworkInfo {
static TimelineNetworkInfo fromJson(Map<String, dynamic> json) {
final String name = json['name'] ?? 'Unknown';
final vapidKey = json['vapid_key'] ?? '';
final nameMainPart = name.split('(').first.trim();
final KnownNetworks network = switch (nameMainPart.toLowerCase()) {
'api' => KnownNetworks.friendica,
'activitypub' => KnownNetworks.activityPub,
'akkoma' => KnownNetworks.pleroma,
'bluesky' => KnownNetworks.bluesky,
'diaspora' => KnownNetworks.diaspora,
'friendica' => KnownNetworks.friendica,
'friendika' => KnownNetworks.friendica,
'gnu social' => KnownNetworks.gnu_social,
'gnusocial' => KnownNetworks.gnu_social,
'hubzilla' => KnownNetworks.hubzilla,
'mastodon' => KnownNetworks.mastodon,
'peertube' => KnownNetworks.peertube,
'pixelfed' => KnownNetworks.pixelfed,
'pleroma' => KnownNetworks.pleroma,
'red' => KnownNetworks.hubzilla,
'redmatrix' => KnownNetworks.hubzilla,
'socialhome' => KnownNetworks.socialhome,
'wordpress' => KnownNetworks.wordpress,
'lemmy' => KnownNetworks.lemmy,
'plume' => KnownNetworks.plume,
'funkwhale' => KnownNetworks.funkwhale,
'nextcloud' => KnownNetworks.nextcloud,
'drupal' => KnownNetworks.drupal,
'firefish' => KnownNetworks.firefish,
'calckey' => KnownNetworks.calckey,
'kbin' => KnownNetworks.kbin,
'threads' => KnownNetworks.threads,
// Clients which are assumed to be interfacing with Friendica if got set as application
// list from blockbot's blockbot_is_fediverse_client
'mastodonandroid' => KnownNetworks.friendica,
'tootdeck-worker' => KnownNetworks.friendica,
'piefed' => KnownNetworks.friendica,
'brighteon' => KnownNetworks.friendica,
'pachli' => KnownNetworks.friendica,
'tusky' => KnownNetworks.friendica,
'mona' => KnownNetworks.friendica,
'mitra' => KnownNetworks.friendica,
'megalodonandroid' => KnownNetworks.friendica,
'fedilab' => KnownNetworks.friendica,
'mastodonapp' => KnownNetworks.friendica,
'toot!' => KnownNetworks.friendica,
'intravnews' => KnownNetworks.friendica,
'pixeldroid' => KnownNetworks.friendica,
'greatnews' => KnownNetworks.friendica,
'protopage' => KnownNetworks.friendica,
'newsfox' => KnownNetworks.friendica,
'vienna' => KnownNetworks.friendica,
'wp-urldetails' => KnownNetworks.friendica,
'husky' => KnownNetworks.friendica,
'activitypub-go-http-client' => KnownNetworks.friendica,
'mobilesafari' => KnownNetworks.friendica,
'mastodon-ios' => KnownNetworks.friendica,
'mastodonpy' => KnownNetworks.friendica,
'techniverse' => KnownNetworks.friendica,
'relatica' => KnownNetworks.friendica,
_ => KnownNetworks.unknown,
};
return TimelineNetworkInfo(
name: name,
vapidKey: vapidKey,
network: network,
);
}
}

View file

@ -181,10 +181,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.17.2"
color_blindness:
dependency: "direct main"
description:
@ -733,30 +733,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.8.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
@ -785,18 +761,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.5.0"
media_kit:
dependency: "direct main"
description:
@ -873,10 +849,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.9.1"
mime:
dependency: transitive
description:
@ -969,10 +945,10 @@ packages:
dependency: "direct main"
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.8.3"
path_parsing:
dependency: transitive
description:
@ -1303,18 +1279,18 @@ packages:
dependency: "direct main"
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.1"
stream_transform:
dependency: transitive
description:
@ -1359,10 +1335,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
version: "0.6.0"
time_machine:
dependency: "direct main"
description:
@ -1547,14 +1523,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.17"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "13.0.0"
volume_controller:
dependency: transitive
description:
@ -1587,6 +1555,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
web_socket_channel:
dependency: transitive
description:
@ -1644,5 +1620,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.2.0-0 <4.0.0"
dart: ">=3.1.0-185.0.dev <4.0.0"
flutter: ">=3.10.0"

View file

@ -68,6 +68,10 @@ flutter:
uses-material-design: true
assets:
- icon/relatica_logo.svg
fonts:
- family: ForkAwesome
fonts:
- asset: fonts/forkawesome-webfont.ttf
parts:
uet-lms:
@ -80,6 +84,7 @@ parts:
stage-packages:
- libsecret-1-0
- libjsoncpp1
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg