1
0
Fork 0
forked from Nexus/nexus

Compare commits

..

No commits in common. "690d2549bc31e8fc25137bcacf49b103b641636a" and "a1401f20ea3238e20c15c4a0329da2c0abd09442" have entirely different histories.

14 changed files with 65 additions and 151 deletions

View file

@ -23,13 +23,6 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v6 uses: actions/setup-go@v6
with:
go-version-file: gomuks/go.mod
- name: Go build
run: |
cd gomuks/pkg/ffi
go build -tags goolm -o ../../../libgomuks.dll -buildmode=c-shared
- name: Build with Flutter - name: Build with Flutter
run: | run: |

View file

@ -18,6 +18,7 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
break; break;
case OS.windows: case OS.windows:
libFileName = "libgomuks.dll"; libFileName = "libgomuks.dll";
env = {"GOCACHE": r"C:\Users\runneradmin\AppData\Local\go-build"};
break; break;
case OS.android: case OS.android:
libFileName = "libgomuks.so"; libFileName = "libgomuks.so";
@ -55,8 +56,9 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
// goheif/dav1d supported on Android would need to fix upstream // goheif/dav1d supported on Android would need to fix upstream
final tags = targetOS == OS.android ? "goolm,noheic" : "goolm"; final tags = targetOS == OS.android ? "goolm,noheic" : "goolm";
print( print(
"Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${libFile.path}...", "Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) from source...",
); );
final result = await Process.run( final result = await Process.run(
"go", "go",

View file

@ -2,7 +2,6 @@ import "dart:async";
import "package:collection/collection.dart"; import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/members_controller.dart"; import "package:nexus/controllers/members_controller.dart";
import "package:nexus/models/configs/author_config.dart"; import "package:nexus/models/configs/author_config.dart";
import "package:nexus/models/membership.dart"; import "package:nexus/models/membership.dart";
@ -13,7 +12,7 @@ class AuthorController extends AsyncNotifier<Membership> {
@override @override
Future<Membership> build() async { Future<Membership> build() async {
final member = await ref.watch( var member = await ref.watch(
MembersController.provider(config.room).selectAsync( MembersController.provider(config.room).selectAsync(
(value) => value.firstWhereOrNull( (value) => value.firstWhereOrNull(
(membership) => membership.userId == config.message.authorId, (membership) => membership.userId == config.message.authorId,
@ -26,12 +25,6 @@ class AuthorController extends AsyncNotifier<Membership> {
: Membership.fromContent( : Membership.fromContent(
IMap(config.message.metadata?["pmp"]), IMap(config.message.metadata?["pmp"]),
config.message.authorId, config.message.authorId,
ref.watch(
ClientStateController.provider.select(
(value) => value?.homeserverUrl,
),
) ??
"",
); );
return Membership( return Membership(

View file

@ -1,7 +1,6 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client_controller.dart"; import "package:nexus/controllers/client_controller.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/models/membership.dart"; import "package:nexus/models/membership.dart";
import "package:nexus/models/requests/get_room_state_request.dart"; import "package:nexus/models/requests/get_room_state_request.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
@ -27,16 +26,8 @@ class MembersController extends AsyncNotifier<IList<Membership>> {
return state.nonNulls return state.nonNulls
.where((member) => member.content["membership"] == "join") .where((member) => member.content["membership"] == "join")
.map( .map(
(membership) => Membership.fromContent( (membership) =>
membership.content, Membership.fromContent(membership.content, membership.stateKey!),
membership.stateKey!,
ref.watch(
ClientStateController.provider.select(
(value) => value?.homeserverUrl,
),
) ??
"",
),
) )
.toIList(); .toIList();
} }

View file

@ -1,9 +1,7 @@
import "package:collection/collection.dart"; import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/new_events_controller.dart"; import "package:nexus/controllers/new_events_controller.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart";
import "package:nexus/models/read_receipt.dart"; import "package:nexus/models/read_receipt.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
@ -12,13 +10,6 @@ class RoomsController extends Notifier<IMap<String, Room>> {
IMap<String, Room> build() => const IMap.empty(); IMap<String, Room> build() => const IMap.empty();
void update(IMap<String, Room> rooms, ISet<String> leftRooms) { void update(IMap<String, Room> rooms, ISet<String> leftRooms) {
final homeserver =
ref.watch(
ClientStateController.provider.select(
(value) => value?.homeserverUrl,
),
) ??
"";
final merged = rooms.entries.fold(state, (acc, entry) { final merged = rooms.entries.fold(state, (acc, entry) {
final roomId = entry.key; final roomId = entry.key;
final incoming = entry.value; final incoming = entry.value;
@ -46,13 +37,7 @@ class RoomsController extends Notifier<IMap<String, Room>> {
roomId, roomId,
existing?.copyWith( existing?.copyWith(
hasMore: incoming.hasMore, hasMore: incoming.hasMore,
metadata: metadata: incoming.metadata ?? existing.metadata,
incoming.metadata?.copyWith(
avatar:
incoming.metadata?.avatar?.mxcToHttps(homeserver) ??
existing.metadata?.avatar,
) ??
existing.metadata,
events: events!, events: events!,
state: incoming.state.entries.fold( state: incoming.state.entries.fold(
existing.state, existing.state,
@ -82,11 +67,7 @@ class RoomsController extends Notifier<IMap<String, Room>> {
), ),
), ),
) ?? ) ??
incoming.copyWith( incoming,
metadata: incoming.metadata?.copyWith(
avatar: incoming.metadata?.avatar?.mxcToHttps(homeserver),
),
),
); );
}); });

View file

@ -1,4 +1,3 @@
import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
@ -100,12 +99,7 @@ class SpacesController extends Notifier<IList<Space>> {
.toIList(); .toIList();
return <Space>[ return <Space>[
Space( Space(id: "home", title: "Home", icon: Icons.home, children: homeRooms),
id: "home",
title: "Home",
icon: Icons.home,
children: homeRooms,
),
Space( Space(
id: "dms", id: "dms",
title: "Direct Messages", title: "Direct Messages",
@ -113,24 +107,7 @@ class SpacesController extends Notifier<IList<Space>> {
children: dmRooms, children: dmRooms,
), ),
...topLevelSpacesList, ...topLevelSpacesList,
] ].toIList();
.map(
(space) => space.copyWith(
children: space.children
.sortedBy(
(element) =>
element
.metadata
?.sortingTimestamp
.millisecondsSinceEpoch ??
0,
)
.sortedBy((room) => room.metadata?.unreadMessages ?? 0)
.reversed
.toIList(),
),
)
.toIList();
} }
static final provider = NotifierProvider<SpacesController, IList<Space>>( static final provider = NotifierProvider<SpacesController, IList<Space>>(

View file

@ -1,5 +1,4 @@
extension MxcToHttps on Uri { extension MxcToHttps on Uri {
Uri mxcToHttps(String homeserver) => Uri.parse( Uri mxcToHttps(String homeserver) =>
homeserver, Uri.parse("${homeserver}_matrix/client/v1/media/download/$host$path");
).resolve("_matrix/client/v1/media/download/$host$path");
} }

View file

@ -1,6 +1,5 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart";
part "membership.freezed.dart"; part "membership.freezed.dart";
@freezed @freezed
@ -15,11 +14,8 @@ abstract class Membership with _$Membership {
factory Membership.fromContent( factory Membership.fromContent(
IMap<String, dynamic> content, IMap<String, dynamic> content,
String userId, String userId,
String homeserver,
) => Membership( ) => Membership(
avatarUrl: Uri.tryParse( avatarUrl: Uri.tryParse(content["avatar_url"] ?? ""),
content["avatar_url"] ?? "",
)?.mxcToHttps(homeserver),
userId: userId, userId: userId,
displayName: content["displayname"] ?? userId.substring(1).split(":").first, displayName: content["displayname"] ?? userId.substring(1).split(":").first,
); );

View file

@ -2,8 +2,10 @@ import "package:color_hash/color_hash.dart";
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_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/cross_cache_controller.dart"; import "package:nexus/controllers/cross_cache_controller.dart";
import "package:nexus/helpers/extensions/get_headers.dart"; import "package:nexus/helpers/extensions/get_headers.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart";
class AvatarOrHash extends ConsumerWidget { class AvatarOrHash extends ConsumerWidget {
final Uri? avatar; final Uri? avatar;
@ -46,7 +48,16 @@ class AvatarOrHash extends ConsumerWidget {
? fallback ?? box ? fallback ?? box
: Image( : Image(
image: CachedNetworkImage( image: CachedNetworkImage(
avatar.toString(), avatar!
.mxcToHttps(
ref.watch(
ClientStateController.provider.select(
(value) => value?.homeserverUrl,
),
) ??
"",
)
.toString(),
ref.watch(CrossCacheController.provider), ref.watch(CrossCacheController.provider),
headers: ref.headers, headers: ref.headers,
), ),

View file

@ -1,48 +0,0 @@
import "dart:math";
import "package:cross_cache/cross_cache.dart";
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/cross_cache_controller.dart";
import "package:nexus/helpers/extensions/get_headers.dart";
import "package:nexus/widgets/error_dialog.dart";
class ExpandableImage extends ConsumerWidget {
final Widget child;
final String? source;
const ExpandableImage(this.source, {required this.child, super.key});
@override
Widget build(BuildContext context, WidgetRef ref) => InkWell(
onTap: source == null
? null
: () => showDialog(
context: context,
builder: (_) => LayoutBuilder(
builder: (context, constraints) => Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(constraints.maxWidth / 100),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: min(constraints.maxWidth, 1000),
),
child: InteractiveViewer(
child: Image(
fit: BoxFit.contain,
errorBuilder: (_, error, stackTrace) => ErrorDialog(
"Loading failed for $source\nError: $error",
stackTrace,
),
image: CachedNetworkImage(
source!,
ref.watch(CrossCacheController.provider),
headers: ref.headers,
),
),
),
),
),
),
),
child: child,
);
}

View file

@ -1,3 +1,4 @@
import "dart:math";
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_chat_core/flutter_chat_core.dart"; import "package:flutter_chat_core/flutter_chat_core.dart";
@ -5,7 +6,6 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:flyer_chat_image_message/flyer_chat_image_message.dart"; import "package:flyer_chat_image_message/flyer_chat_image_message.dart";
import "package:nexus/controllers/cross_cache_controller.dart"; import "package:nexus/controllers/cross_cache_controller.dart";
import "package:nexus/helpers/extensions/get_headers.dart"; import "package:nexus/helpers/extensions/get_headers.dart";
import "package:nexus/widgets/chat_page/expandable_image.dart";
class ExpandableImageMessage extends ConsumerWidget { class ExpandableImageMessage extends ConsumerWidget {
final ImageMessage message; final ImageMessage message;
@ -14,8 +14,31 @@ class ExpandableImageMessage extends ConsumerWidget {
const ExpandableImageMessage(this.message, {required this.index, super.key}); const ExpandableImageMessage(this.message, {required this.index, super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) => ExpandableImage( Widget build(BuildContext context, WidgetRef ref) => InkWell(
onTap: () => showDialog(
context: context,
builder: (_) => LayoutBuilder(
builder: (context, constraints) => Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(constraints.maxWidth / 100),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: min(constraints.maxWidth, 1000),
),
child: InteractiveViewer(
child: Image(
fit: BoxFit.contain,
image: CachedNetworkImage(
message.source, message.source,
ref.watch(CrossCacheController.provider),
headers: ref.headers,
),
),
),
),
),
),
),
child: FlyerChatImageMessage( child: FlyerChatImageMessage(
customImageProvider: CachedNetworkImage( customImageProvider: CachedNetworkImage(
message.source, message.source,

View file

@ -3,7 +3,6 @@ import "package:flutter/material.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/appbar.dart";
import "package:nexus/widgets/avatar_or_hash.dart"; import "package:nexus/widgets/avatar_or_hash.dart";
import "package:nexus/widgets/chat_page/expandable_image.dart";
import "package:nexus/widgets/chat_page/room_menu.dart"; import "package:nexus/widgets/chat_page/room_menu.dart";
class RoomAppbar extends StatelessWidget implements PreferredSizeWidget { class RoomAppbar extends StatelessWidget implements PreferredSizeWidget {
@ -25,14 +24,11 @@ class RoomAppbar extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) => Appbar( Widget build(BuildContext context) => Appbar(
leading: isDesktop leading: isDesktop
? ExpandableImage( ? AvatarOrHash(
room.metadata?.avatar?.toString(),
child: AvatarOrHash(
room.metadata?.avatar, room.metadata?.avatar,
room.metadata?.name ?? "Unnamed Rooms", room.metadata?.name ?? "Unnamed Rooms",
height: 24, height: 24,
fallback: Icon(Icons.numbers), fallback: Icon(Icons.numbers),
),
) )
: DrawerButton(onPressed: () => onOpenDrawer(context)), : DrawerButton(onPressed: () => onOpenDrawer(context)),
scrolledUnderElevation: 0, scrolledUnderElevation: 0,

View file

@ -14,7 +14,7 @@ import "package:nexus/helpers/extensions/show_context_menu.dart";
import "package:nexus/models/relation_type.dart"; import "package:nexus/models/relation_type.dart";
import "package:nexus/models/requests/report_request.dart"; import "package:nexus/models/requests/report_request.dart";
import "package:nexus/widgets/chat_page/composer/chat_box.dart"; import "package:nexus/widgets/chat_page/composer/chat_box.dart";
import "package:nexus/widgets/chat_page/expandable_image_message.dart"; import "package:nexus/widgets/chat_page/image_message.dart";
import "package:nexus/widgets/chat_page/member_list.dart"; import "package:nexus/widgets/chat_page/member_list.dart";
import "package:nexus/widgets/chat_page/wrappers/message_wrapper.dart"; import "package:nexus/widgets/chat_page/wrappers/message_wrapper.dart";
import "package:nexus/widgets/chat_page/room_appbar.dart"; import "package:nexus/widgets/chat_page/room_appbar.dart";

View file

@ -43,7 +43,7 @@ static void my_application_activate(GApplication* application) {
} }
} }
#endif #endif
gtk_widget_set_size_request(GTK_WIDGET(window), 250, -1); gtk_widget_set_size_request(GTK_WIDGET(window), 500, 500);
if (use_header_bar) { if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar)); gtk_widget_show(GTK_WIDGET(header_bar));