Remove flutter chat #26

Manually merged
Henry-Hiles merged 108 commits from remove-flutter-chat into main 2026-05-22 15:26:28 -04:00
3 changed files with 66 additions and 43 deletions
Showing only changes of commit 881c76359b - Show all commits

custom link previews

Henry Hiles 2026-05-12 20:32:40 -04:00
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs

View file

@ -4,13 +4,14 @@ import "package:http/http.dart";
import "package:nexus/controllers/client_state_controller.dart"; import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/header_controller.dart"; import "package:nexus/controllers/header_controller.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart"; import "package:nexus/helpers/extensions/mxc_to_https.dart";
import "package:nexus/models/open_graph_data.dart";
class UrlPreviewController extends AsyncNotifier<LinkPreviewData?> { class UrlPreviewController extends AsyncNotifier<OpenGraphData?> {
final String link; final String link;
UrlPreviewController(this.link); UrlPreviewController(this.link);
@override @override
Future<LinkPreviewData?> build() async { Future<OpenGraphData?> build() async {
final homeserver = ref.watch(ClientStateController.provider)?.homeserverUrl; final homeserver = ref.watch(ClientStateController.provider)?.homeserverUrl;
if (homeserver != null && !link.contains("matrix.to")) { if (homeserver != null && !link.contains("matrix.to")) {
@ -23,28 +24,15 @@ class UrlPreviewController extends AsyncNotifier<LinkPreviewData?> {
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {
final decodedValue = json.decode(response.body); final decodedValue = json.decode(response.body) as Map?;
final mxc = decodedValue["og:image"]; if (decodedValue?.isNotEmpty == true) return null;
final mxc = decodedValue!["og:image"];
final image = mxc == null final image = mxc == null
? null ? null
: Uri.tryParse(mxc)?.mxcToHttps(homeserver); : Uri.tryParse(mxc)?.mxcToHttps(homeserver);
return LinkPreviewData( return OpenGraphData.fromJson({...decodedValue, "og:image": image});
link: link,
title: decodedValue["og:title"],
description: decodedValue["og:description"],
image: image == null
? null
: ImagePreviewData(
url: image.toString(),
width:
(decodedValue["og:image:width"] as int?)?.toDouble() ??
0,
height:
(decodedValue["og:image:height"] as int?)?.toDouble() ??
0,
),
);
} }
} }
} }
@ -53,7 +41,7 @@ class UrlPreviewController extends AsyncNotifier<LinkPreviewData?> {
} }
static final provider = AsyncNotifierProvider.autoDispose static final provider = AsyncNotifierProvider.autoDispose
.family<UrlPreviewController, LinkPreviewData?, String>( .family<UrlPreviewController, OpenGraphData?, String>(
UrlPreviewController.new, UrlPreviewController.new,
); );
} }

View file

@ -0,0 +1,17 @@
import "package:freezed_annotation/freezed_annotation.dart";
part "open_graph_data.freezed.dart";
part "open_graph_data.g.dart";
@freezed
abstract class OpenGraphData with _$OpenGraphData {
const factory OpenGraphData({
@JsonKey(name: "og:title") required String? title,
@JsonKey(name: "og:description") required String? description,
@JsonKey(name: "og:image") required String? imageUrl,
@JsonKey(name: "og:image:width") required double? width,
@JsonKey(name: "og:image:height") required double? height,
}) = _OpenGraphData;
factory OpenGraphData.fromJson(Map<String, Object?> json) =>
_$OpenGraphDataFromJson(json);
}

View file

@ -1,6 +1,5 @@
import "package:cross_cache/cross_cache.dart"; import "package:cross_cache/cross_cache.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_link_previewer/flutter_link_previewer.dart";
import "package:flutter_linkify/flutter_linkify.dart"; import "package:flutter_linkify/flutter_linkify.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/cross_cache_controller.dart"; import "package:nexus/controllers/cross_cache_controller.dart";
@ -109,30 +108,49 @@ class TextMessageWrapper extends ConsumerWidget {
loading: SizedBox.shrink, loading: SizedBox.shrink,
data: (preview) => preview == null data: (preview) => preview == null
? SizedBox.shrink() ? SizedBox.shrink()
: LinkPreview( : InkWell(
onTap: (url) => ref onTap: () => ref
.watch(LaunchHelper.provider) .watch(LaunchHelper.provider)
.launchUrl(Uri.parse(url)), .launchUrl(Uri.parse(link)),
imageBuilder: (url) => Image( child: Card(
child: Column(
children: [
if (preview.title != null)
Text(
preview.title!,
style: theme.textTheme.labelLarge,
),
if (preview.description != null)
Text(preview.description!),
if (preview.imageUrl != null)
Image(
errorBuilder: (_, _, _) =>
SizedBox.shrink(),
width: preview.width,
height: preview.height,
image: CachedNetworkImage( image: CachedNetworkImage(
url, preview.imageUrl!,
ref.watch(CrossCacheController.provider), ref.watch(
CrossCacheController.provider,
),
headers: ref.headers, headers: ref.headers,
), ),
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: (_, _, _) => SizedBox.shrink(),
), ),
text: link, ],
backgroundColor: isSentByMe ),
? colorScheme.inversePrimary // text: link,
: colorScheme.surfaceContainerLow, // backgroundColor: isSentByMe
outsidePadding: EdgeInsets.only(top: 4), // ? colorScheme.inversePrimary
insidePadding: EdgeInsets.symmetric( // : colorScheme.surfaceContainerLow,
vertical: 8, // outsidePadding: EdgeInsets.only(top: 4),
horizontal: 16, // insidePadding: EdgeInsets.symmetric(
// vertical: 8,
// horizontal: 16,
// ),
// linkPreviewData: preview,
// onLinkPreviewDataFetched: (_) => null,
), ),
linkPreviewData: preview,
onLinkPreviewDataFetched: (_) => null,
), ),
), ),
?extra, ?extra,