Skip to content

Commit

Permalink
Add windows support (#392)
Browse files Browse the repository at this point in the history
* chore: add windows platform

* chore: add windows

* fiix: not request permissions on windows

* feat: handle windows notifications

* chore: add windows pipeline

* fix: update windows icon

* chore: simplify stuff

* chore: better dummy values

* fix: remove app id

* ci: fix build

* chore: windows path

* feat: win notifications support

* feat: app_links support

* fix: add scrollcontrollers

* fix: app links

* fix: better check

* chore: remove checks

* feat: update msix settings

* feat: auto msix building

* fix: re-add android and ios to metadata

* chore: remove todo

* feat: use 512 icon

* feat: specify languages

* chore: pin countries

* chore: bump runtime

* fix: simplify config access

* fix: get runtime config

* chore: switch logger

* fix: correctly handle runtime error

* chore: remove unused code

* chore: melos bootstrap

* chore: rm lockfile

* ci: only build windows maually

---------

Co-authored-by: Nicole Ebken <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 30, 2025
1 parent 41ac8d8 commit 581cf06
Show file tree
Hide file tree
Showing 34 changed files with 1,448 additions and 20 deletions.
17 changes: 10 additions & 7 deletions apps/enmeshed/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9"
revision: "17025dd88227cd9532c33fa78f5250d548d87e9a"
channel: "stable"

project_type: app
Expand All @@ -13,14 +13,17 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: android
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: ios
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: windows
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a

# User provided section

Expand Down
Binary file added apps/enmeshed/assets/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions apps/enmeshed/lib/account/contacts/contact_detail_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class ContactDetailScreen extends ContactSharedFilesWidget {
}

class _ContactDetailScreenState extends State<ContactDetailScreen> with ContactSharedFilesMixin<ContactDetailScreen> {
late final ScrollController _scrollController;

late final Session _session;

IdentityDVO? _contact;
Expand All @@ -33,6 +35,8 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> with ContactS
void initState() {
super.initState();

_scrollController = ScrollController();

_session = GetIt.I.get<EnmeshedRuntime>().getSession(widget.accountId);

_reload();
Expand All @@ -50,6 +54,8 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> with ContactS

@override
void dispose() {
_scrollController.dispose();

for (final subscription in _subscriptions) {
subscription.cancel();
}
Expand Down Expand Up @@ -77,8 +83,10 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> with ContactS
await loadSharedFiles(syncBefore: true);
},
child: Scrollbar(
controller: _scrollController,
thumbVisibility: true,
child: ListView(
controller: _scrollController,
children: [
ContactDetailHeader(contact: contact),
ContactStatusInfoContainer(contact: contact),
Expand Down
8 changes: 8 additions & 0 deletions apps/enmeshed/lib/account/home/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class HomeView extends StatefulWidget {
}

class _HomeViewState extends State<HomeView> {
late final ScrollController _scrollController;

int _unreadMessagesCount = 0;
List<MessageDVO>? _messages;
List<LocalRequestDVO>? _requests;
Expand All @@ -31,6 +33,8 @@ class _HomeViewState extends State<HomeView> {
void initState() {
super.initState();

_scrollController = ScrollController();

_reload();

final runtime = GetIt.I.get<EnmeshedRuntime>();
Expand All @@ -46,6 +50,8 @@ class _HomeViewState extends State<HomeView> {

@override
void dispose() {
_scrollController.dispose();

for (final subscription in _subscriptions) {
subscription.cancel();
}
Expand All @@ -67,8 +73,10 @@ class _HomeViewState extends State<HomeView> {
return RefreshIndicator(
onRefresh: () => _reload(syncBefore: true),
child: Scrollbar(
controller: _scrollController,
thumbVisibility: true,
child: ListView(
controller: _scrollController,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
Expand Down
2 changes: 2 additions & 0 deletions apps/enmeshed/lib/core/setup_push.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import 'package:logger/logger.dart';
import 'package:push/push.dart';

Future<void> setupPush(EnmeshedRuntime runtime) async {
if (Platform.isWindows) return;

final logger = GetIt.I.get<Logger>();

// this will timeout e.g. on the ios simulator
Expand Down
3 changes: 2 additions & 1 deletion apps/enmeshed/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';

import 'package:croppy/croppy.dart';
import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart';
Expand Down Expand Up @@ -26,7 +27,7 @@ import 'splash_screen.dart';

void main() async {
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
if (Platform.isAndroid || Platform.isIOS) FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);

timeago.setLocaleMessages('de', timeago.DeMessages());
timeago.setLocaleMessages('en', timeago.EnMessages());
Expand Down
50 changes: 40 additions & 10 deletions apps/enmeshed/lib/splash_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:go_router/go_router.dart';
import 'package:logger/logger.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:renderers/renderers.dart';
import 'package:win32_registry/win32_registry.dart';

import 'core/core.dart';

Expand Down Expand Up @@ -64,17 +65,20 @@ class _SplashScreenState extends State<SplashScreen> {
Future<void> _init(GoRouter router) async {
await GetIt.I.reset();

final logger = Logger(printer: SimplePrinter(colors: false));
GetIt.I.registerSingleton(logger);
GetIt.I.registerSingleton<AbstractUrlLauncher>(UrlLauncher());

// TODO(jkoenig134): we should probably ask for permission when we need it
await Permission.camera.request();
final cameraStatus = await Permission.camera.request();
if (!cameraStatus.isGranted) {
logger.w('Camera permission is (permanently) denied');
}

if (Platform.isAndroid && kDebugMode) {
await InAppWebViewController.setWebContentsDebuggingEnabled(true);
}

final logger = Logger(printer: SimplePrinter(colors: false));
GetIt.I.registerSingleton(logger);
GetIt.I.registerSingleton<AbstractUrlLauncher>(UrlLauncher());

final runtime = EnmeshedRuntime(
logger: logger,
runtimeConfig: (
Expand All @@ -87,6 +91,7 @@ class _SplashScreenState extends State<SplashScreen> {
),
);
GetIt.I.registerSingletonAsync<EnmeshedRuntime>(() async => runtime.run());

await GetIt.I.allReady();

await setupPush(runtime);
Expand All @@ -101,10 +106,10 @@ class _SplashScreenState extends State<SplashScreen> {

await runtime.registerUIBridge(AppUIBridge(logger: logger, router: router));

await _registerWindowsSchemeForDebugMode('nmshd-dev');

final appLinks = AppLinks();
appLinks.uriLinkStream.listen((Uri? uri) {
if (uri != null) GetIt.I.get<EnmeshedRuntime>().stringProcessor.processURL(url: uri.toString());
});
appLinks.uriLinkStream.listen(_processUri);

final accounts = await runtime.accountServices.getAccounts();
final accountsNotInDeletion = await runtime.accountServices.getAccountsNotInDeletion();
Expand All @@ -123,8 +128,33 @@ class _SplashScreenState extends State<SplashScreen> {
}

final initialAppLink = await appLinks.getInitialLink();
if (initialAppLink != null) {
await GetIt.I.get<EnmeshedRuntime>().stringProcessor.processURL(url: initialAppLink.toString());
await _processUri(initialAppLink);
}

Future<void> _processUri(Uri? uri) async {
if (uri == null) return;

final uriString = uri.toString().replaceAll('nmshd-dev://', 'nmshd://').replaceAll('qr/#', 'qr#');
GetIt.I.get<Logger>().i("Processing URL '$uriString'");

final result = await GetIt.I.get<EnmeshedRuntime>().stringProcessor.processURL(url: uriString);
if (result.isError) {
GetIt.I.get<Logger>().e("Processing URL '$uriString' failed with code '${result.error.code}' and message '${result.error.message}'");
}
}
}

Future<void> _registerWindowsSchemeForDebugMode(String scheme) async {
if (!Platform.isWindows || !kDebugMode) return;

final appPath = Platform.resolvedExecutable;

final protocolRegKey = 'Software\\Classes\\$scheme';
const protocolRegValue = RegistryValue('URL Protocol', RegistryValueType.string, '');
const protocolCmdRegKey = r'shell\open\command';
final protocolCmdRegValue = RegistryValue('', RegistryValueType.string, '"$appPath" "%1"');

Registry.currentUser.createKey(protocolRegKey)
..createValue(protocolRegValue)
..createKey(protocolCmdRegKey).createValue(protocolCmdRegValue);
}
49 changes: 49 additions & 0 deletions apps/enmeshed/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.19.0"
console:
dependency: transitive
description:
name: console
sha256: e04e7824384c5b39389acdd6dc7d33f3efe6b232f6f16d7626f194f6a01ad69a
url: "https://pub.dev"
source: hosted
version: "4.1.0"
croppy:
dependency: "direct main"
description:
Expand Down Expand Up @@ -762,6 +770,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.2"
msix:
dependency: "direct dev"
description:
path: "."
ref: "Fix-Flutter-3.27"
resolved-ref: "955467338b11ddcd789a37d268e9cfd884a94b17"
url: "https://github.com/h4h13/msix.git"
source: git
version: "3.16.8"
open_file:
dependency: "direct main"
description:
Expand Down Expand Up @@ -826,6 +843,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.0.3"
package_config:
dependency: transitive
description:
name: package_config
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
package_info_plus:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1002,6 +1027,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.13.4"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
url: "https://pub.dev"
source: hosted
version: "2.1.5"
push:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1373,6 +1406,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.10.0"
win32_registry:
dependency: "direct main"
description:
name: win32_registry
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
url: "https://pub.dev"
source: hosted
version: "1.1.5"
windows_notification:
dependency: transitive
description:
name: windows_notification
sha256: be3e650874615f315402c9b9f3656e29af156709c4b5cc272cb4ca0ab7ba94a8
url: "https://pub.dev"
source: hosted
version: "1.3.0"
wolt_modal_sheet:
dependency: "direct main"
description:
Expand Down
24 changes: 24 additions & 0 deletions apps/enmeshed/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,17 @@ dependencies:
value_renderer: ^1.0.0
vector_graphics: ^1.1.13
very_good_analysis: ^6.0.0
win32_registry: ^1.1.5
wolt_modal_sheet: ^0.5.0

dev_dependencies:
flutter_launcher_icons: ^0.14.1
flutter_test:
sdk: flutter
msix:
git:
url: https://github.com/h4h13/msix.git
ref: Fix-Flutter-3.27
translations_cleaner: ^0.0.5
vector_graphics_compiler: ^1.1.12

Expand All @@ -81,6 +86,9 @@ flutter_icons:
image_path: "assets/icon.png"
android: true
ios: true
windows:
generate: true
image_path: "assets/icon-512.png"
remove_alpha_ios: true
image_path_ios_dark_transparent: "assets/icon_dark.png"
image_path_ios_tinted_grayscale: "assets/icon_grayscale.png"
Expand All @@ -104,3 +112,19 @@ flutter_native_splash:

android: true
ios: true

# dart run msix:create
msix_config:
display_name: enmeshed
publisher_display_name: js-soft
identity_name: js-soft.enmeshed
publisher: CN=CB3048C3-A086-471C-AF11-83ABB7396C98
store: true
protocol_activation: nmshd
logo_path: assets/icon-512.png
start_menu_icon_path: assets/icon-512.png
tile_icon_path: assets/icon-512.png
icons_background_color: transparent
build_windows: false
languages: en-us, de-de
# capabilities: "internetClient,internetClientServer,privateNetworkClientServer"
17 changes: 17 additions & 0 deletions apps/enmeshed/windows/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
flutter/ephemeral/

# Visual Studio user-specific files.
*.suo
*.user
*.userosscache
*.sln.docstates

# Visual Studio build-related files.
x64/
x86/

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
Loading

0 comments on commit 581cf06

Please sign in to comment.