diff --git a/lib/chat/bootstrap/bootstrap_model.dart b/lib/chat/bootstrap/bootstrap_model.dart index e08436e..cecc98e 100644 --- a/lib/chat/bootstrap/bootstrap_model.dart +++ b/lib/chat/bootstrap/bootstrap_model.dart @@ -18,7 +18,10 @@ class BootstrapModel extends SafeChangeNotifier { final Client _client; final FlutterSecureStorage _secureStorage; - Future isBootrapNeeded() async { + Future isBootrapNeeded() async => + _client.isUnknownSession && _client.encryption!.crossSigning.enabled; + + Future isBootrapNeededFull() async { if (!_client.encryptionEnabled) return true; await _client.accountDataLoading; await _client.userDeviceKeysLoading; diff --git a/lib/chat/view/events/chat_message_bubble.dart b/lib/chat/view/events/chat_message_bubble.dart index 12d2d1a..ea82c58 100644 --- a/lib/chat/view/events/chat_message_bubble.dart +++ b/lib/chat/view/events/chat_message_bubble.dart @@ -11,6 +11,7 @@ import '../../chat_model.dart'; import '../chat_avatar.dart'; import '../chat_profile_dialog.dart'; import 'chat_event_status_icon.dart'; +import 'chat_html_message.dart'; import 'chat_message_attachment_indicator.dart'; import 'chat_message_bubble_shape.dart'; import 'chat_message_media_avatar.dart'; @@ -196,13 +197,19 @@ class _ChatMessageBubbleContent extends StatelessWidget { decoration: TextDecoration.lineThrough, ), ) - : SelectableText.rich( - TextSpan( - style: messageStyle, - text: displayEvent.body, - ), - style: messageStyle, - ), + : event.isRichMessage + ? HtmlMessage( + html: html, + room: timeline.room, + defaultTextColor: context.colorScheme.onSurface, + ) + : SelectableText.rich( + TextSpan( + style: messageStyle, + text: displayEvent.body, + ), + style: messageStyle, + ), ), const SizedBox( height: kBigPadding, diff --git a/lib/main.dart b/lib/main.dart index 407f4d8..743a8e3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:window_manager/window_manager.dart'; import 'package:yaru/yaru.dart'; @@ -12,10 +14,12 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); } else { await YaruWindowTitleBar.ensureInitialized(); - windowManager.waitUntilReadyToShow(windowOptions, () async { - await windowManager.show(); - await windowManager.focus(); - }); + if (Platform.isMacOS) { + windowManager.waitUntilReadyToShow(windowOptions, () async { + await windowManager.show(); + await windowManager.focus(); + }); + } } registerDependencies(); diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 5a53fe6..f89520e 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -1,34 +1,14 @@ -# Project-level configuration. cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. set(BINARY_NAME "nebuchadnezzar") -# The unique GTK application identifier for this application. See: -# https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "org.feichtmeier.nebuchadnezzar") +set(APPLICATION_ID "org.feichtmeier.Nebuchadnezzar") -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. cmake_policy(SET CMP0063 NEW) -set(USE_LIBHANDY ON) - -# Load bundled libraries from the lib/ directory relative to the binary. set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") -# Root filesystem for cross-building. -if(FLUTTER_TARGET_PLATFORM_SYSROOT) - set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# Define build configuration options. +# Configure build options. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) @@ -37,10 +17,6 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() # Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) @@ -48,8 +24,9 @@ function(APPLY_STANDARD_SETTINGS TARGET) target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") endfunction() -# Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. add_subdirectory(${FLUTTER_MANAGED_DIR}) # System-level dependencies. @@ -58,27 +35,16 @@ pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") -# Define the application target. To change its name, change BINARY_NAME above, -# not the value here, or `flutter run` will no longer work. -# -# Any new source files that you add to the application should be added here. +# Application build add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. apply_standard_settings(${BINARY_NAME}) - -# Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) - -# Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) - # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of @@ -88,11 +54,11 @@ set_target_properties(${BINARY_NAME} RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) - # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) +target_link_libraries(${BINARY_NAME} PRIVATE ${MIMALLOC_LIB}) # === Installation === # By default, "installing" just makes a relocatable bundle in the build @@ -119,17 +85,11 @@ install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR} install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) - install(FILES "${bundled_library}" +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -endforeach(bundled_library) - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) +endif() # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. @@ -144,4 +104,4 @@ install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -endif() +endif() \ No newline at end of file diff --git a/linux/my_application.cc b/linux/my_application.cc index f8911d9..1d848bd 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -1,6 +1,9 @@ #include "my_application.h" -#include +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif #include "flutter/generated_plugin_registrant.h" @@ -14,21 +17,47 @@ G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) // Implements GApplication::activate. static void my_application_activate(GApplication* application) { MyApplication* self = MY_APPLICATION(application); - GtkWindow* window = GTK_WINDOW(hdy_application_window_new()); - gtk_window_set_application(window, GTK_APPLICATION(application)); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { - gtk_window_set_default_size(window, 800, 600); - gtk_widget_show(GTK_WIDGET(window)); + } else { + gtk_window_set_title(window, "Nebuchadnezzar"); + } + GdkGeometry geometry_min; + geometry_min.min_width = 500; + geometry_min.min_height = 700; + gtk_window_set_geometry_hints(window, nullptr, &geometry_min, GDK_HINT_MIN_SIZE); + gtk_window_set_default_size(window, 950, 820); g_autoptr(FlDartProject) project = fl_dart_project_new(); fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); FlView* view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + gtk_widget_show(GTK_WIDGET(window)); + gtk_widget_show(GTK_WIDGET(view)); gtk_widget_grab_focus(GTK_WIDGET(view)); } @@ -91,4 +120,4 @@ MyApplication* my_application_new() { "application-id", APPLICATION_ID, "flags", G_APPLICATION_NON_UNIQUE, nullptr)); -} +} \ No newline at end of file