Skip to content

Commit

Permalink
Some work towards watch support
Browse files Browse the repository at this point in the history
  • Loading branch information
Codel1417 committed Nov 25, 2024
1 parent ab428e1 commit 7d00d90
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 47 deletions.
2 changes: 1 addition & 1 deletion lib/Backend/favorite_actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ class FavoriteActions extends _$FavoriteActions {
await HiveProxy.clear<FavoriteAction>(favoriteActionsBox);
await HiveProxy.addAll<FavoriteAction>(favoriteActionsBox, state);
updateShortcuts(state, ref);
updateWearActions(state, ref);
ref.read(updateWearActionsProvider);
}
}
77 changes: 63 additions & 14 deletions lib/Backend/wear_bridge.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:collection/collection.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:tail_app/Backend/sensors.dart';
import 'package:watch_connectivity/watch_connectivity.dart';

import 'Definitions/Action/base_action.dart';
import 'action_registry.dart';
import 'favorite_actions.dart';

part 'wear_bridge.freezed.dart';
part 'wear_bridge.g.dart';

final Logger _wearLogger = Logger('Wear');
Expand All @@ -30,7 +31,7 @@ Future<void> initWear(InitWearRef ref) async {
(event) => _wearLogger.info("Watch Context: $event"),
);

updateWearActions(ref.read(favoriteActionsProvider), ref);
ref.read(updateWearActionsProvider);
} catch (e, s) {
_wearLogger.severe("exception setting up Wear $e", e, s);
}
Expand Down Expand Up @@ -62,24 +63,72 @@ Future<Map<String, dynamic>> applicationContext() {
);
}

Future<void> updateWearActions(BuiltList<FavoriteAction> favoriteActions, Ref ref) async {
@Riverpod()
Future<void> updateWearActions(UpdateWearActionsRef ref) async {
try {
Iterable<BaseAction> allActions = favoriteActions
Iterable<BaseAction> allActions = ref
.read(favoriteActionsProvider)
.map(
(e) => ref.read(getActionFromUUIDProvider(e.actionUUID)),
)
.whereNotNull();
final Map<String, String> favoriteMap = Map.fromEntries(allActions.map((e) => MapEntry(e.uuid, e.name)));
final Map<String, String> map = Map.fromEntries(
[
MapEntry("actions", favoriteMap.values.join("_")),
MapEntry("uuid", favoriteMap.keys.join("_")),
],
);
.nonNulls;
//TODO: refresh when trigger toggled state changes
BuiltList<Trigger> triggers = ref.read(triggerListProvider);
final List<WearActionData> favoriteMap = allActions.map((e) => WearActionData(uuid: e.uuid, name: e.name)).toList();
final List<WearTriggerData> triggersMap = triggers.map((e) => WearTriggerData(uuid: e.uuid, name: e.triggerDefinition!.name, enabled: e.enabled)).toList();

final WearData wearData = WearData(favoriteActions: favoriteMap, configuredTriggers: triggersMap);
if (await _watch.isReachable) {
await _watch.sendMessage(map);
await _watch.updateApplicationContext(wearData.toJson());
}
} catch (e, s) {
_wearLogger.severe("Unable to send favorite actions to watch", e, s);
}
}

@freezed
class WearData with _$WearData {
const factory WearData({
required List<WearActionData> favoriteActions,
required List<WearTriggerData> configuredTriggers,
}) = _WearData;

factory WearData.fromJson(Map<String, dynamic> json) => _$WearDataFromJson(json);
}

@freezed
class WearTriggerData with _$WearTriggerData {
const factory WearTriggerData({
required String name,
required String uuid,
required bool enabled,
}) = _WearTriggerData;

factory WearTriggerData.fromJson(Map<String, dynamic> json) => _$WearTriggerDataFromJson(json);
}

@freezed
class WearActionData with _$WearActionData {
const factory WearActionData({
required String name,
required String uuid,
}) = _WearActionData;

factory WearActionData.fromJson(Map<String, dynamic> json) => _$WearActionDataFromJson(json);
}

@freezed
class WearCommand with _$WearCommand {
const factory WearCommand({
required WearCommandType commandType,
required String uuid,
@Default(false) bool boolean,
}) = _WearCommand;

factory WearCommand.fromJson(Map<String, dynamic> json) => _$WearCommandFromJson(json);
}

enum WearCommandType {
runAction,
toggleTrigger,
}
10 changes: 10 additions & 0 deletions lib/Frontend/WatchUI/actions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';

class Actions extends StatelessWidget {
const Actions({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Container();
}
}
19 changes: 19 additions & 0 deletions lib/Frontend/WatchUI/main_menu.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:flutter/material.dart';

import '../translation_string_definitions.dart';

class MainMenu extends StatelessWidget {
const MainMenu({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return ListView(
children: [
FilledButton(onPressed: () {}, child: Text("Favorite Actions")),
FilledButton(onPressed: () {}, child: Text(homePage())),
FilledButton(onPressed: () {}, child: Text(triggersPage())),
FilledButton(onPressed: () {}, child: Text("Gear")),
],
);
}
}
10 changes: 10 additions & 0 deletions lib/Frontend/WatchUI/triggers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';

class Triggers extends StatelessWidget {
const Triggers({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Container();
}
}
121 changes: 95 additions & 26 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:install_referrer/install_referrer.dart';
import 'package:intl/intl.dart';
import 'package:is_wear/is_wear.dart';
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Expand All @@ -28,6 +29,7 @@ import 'Backend/favorite_actions.dart';
import 'Backend/logging_wrappers.dart';
import 'Backend/move_lists.dart';
import 'Backend/sensors.dart';
import 'Backend/wear_bridge.dart';
import 'Frontend/Widgets/bt_app_state_controller.dart';
import 'Frontend/go_router_config.dart';
import 'Frontend/translation_string_definitions.dart';
Expand Down Expand Up @@ -80,32 +82,20 @@ Future<String> getSentryEnvironment() async {
return 'production';
}

Future<void> main() async {
Logger.root.level = Level.ALL;
mainLogger.info("Begin");
Logger.root.onRecord.listen((event) {
if (["GoRouter", "Dio"].contains(event.loggerName)) {
return;
}
if (event.level.value < 1000 && event.stackTrace == null) {
logarte.info(event.message, source: event.loggerName);
} else {
logarte.error(event.message, stackTrace: event.stackTrace);
}
});
initFlutter();
Future<void> initMainApp() async {
//initialize the foreground service library
if (Platform.isAndroid) {
FlutterForegroundTask.initCommunicationPort();
}
await startSentryApp(TailApp());
}

initLocale();
await initHive();
Future<void> startSentryApp(Widget child) async {
mainLogger.fine("Init Sentry");
String environment = await getSentryEnvironment();
DynamicConfigInfo dynamicConfigInfo = await getDynamicConfigInfo();
mainLogger.info("Detected Environment: $environment");

//initialize the foreground service library
if (Platform.isAndroid) {
FlutterForegroundTask.initCommunicationPort();
}
await SentryFlutter.init(
(options) async {
options
Expand All @@ -126,16 +116,55 @@ Future<void> main() async {
// Init your App.
// ignore: missing_provider_scope
appRunner: () => runApp(
DefaultAssetBundle(
bundle: SentryAssetBundle(),
child: SentryScreenshotWidget(
child: TailApp(),
),
SentryScreenshotWidget(
child: TailApp(),
),
),
);
}

Future<void> initWearApp() async {
await startSentryApp(TailAppWear());
}

Future<void> main() async {
Logger.root.level = Level.ALL;
mainLogger.info("Begin");
Logger.root.onRecord.listen((event) {
if (["GoRouter", "Dio"].contains(event.loggerName)) {
return;
}
if (event.level.value < 1000 && event.stackTrace == null) {
logarte.info(event.message, source: event.loggerName);
} else {
logarte.error(event.message, stackTrace: event.stackTrace);
}
});
initFlutter();
await initLocale();
await initHive();

if (await isWear()) {
initWearApp();
} else {
initMainApp();
}
}

Future<bool> isWear() async {
final IsWear isWearPlugin = IsWear();
bool? result = await isWearPlugin.check().then((value) {
return value;
}).catchError((onError) {
return false;
});
if (result == null) {
return false;
} else {
return result;
}
}

void initFlutter() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized()..addObserver(WidgetBindingLogger());
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); // keeps the splash screen visible
Expand Down Expand Up @@ -240,6 +269,7 @@ class TailApp extends ConsumerWidget {
return WithForegroundTask(
key: GlobalKey(debugLabel: "foregroundTask"),
child: ProviderScope(
key: GlobalKey(debugLabel: "providerScope"),
observers: [
RiverpodProviderObserver(),
],
Expand Down Expand Up @@ -275,6 +305,45 @@ class TailApp extends ConsumerWidget {
}
}

class TailAppWear extends ConsumerWidget {
TailAppWear({super.key}) {
// Platform messages may fail, so we use a try/catch PlatformException.
mainLogger.info('Starting app');
}

// This widget is the root of your application.
@override
Widget build(BuildContext context, WidgetRef ref) {
return ProviderScope(
key: GlobalKey(debugLabel: "providerScope"),
observers: [
RiverpodProviderObserver(),
],
child: _EagerInitialization(
child: ValueListenableBuilder(
valueListenable: SentryHive.box(settings).listenable(keys: [appColor]),
builder: (BuildContext context, value, Widget? child) {
unawaited(setupSystemColor(context));
Future(FlutterNativeSplash.remove); //remove the splash screen one frame later
Color color = Color(HiveProxy.getOrDefault(settings, appColor, defaultValue: appColorDefault));
return MaterialApp.router(
title: title(),
color: color,
theme: buildTheme(Brightness.light, color),
darkTheme: buildTheme(Brightness.dark, color),
routerConfig: router,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
themeMode: ThemeMode.system,
debugShowCheckedModeBanner: false,
);
},
),
),
);
}
}

ThemeData buildTheme(Brightness brightness, Color color) {
if (brightness == Brightness.light) {
return ThemeData(
Expand Down Expand Up @@ -365,7 +434,7 @@ class _EagerInitialization extends ConsumerWidget {
//ref.watch(favoriteActionsProvider);
ref.watch(appShortcutsProvider);
if (kDebugMode) {
//ref.watch(initWearProvider);
ref.watch(initWearProvider);
}
return child;
}
Expand Down
16 changes: 12 additions & 4 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
is_wear:
dependency: "direct main"
description:
name: is_wear
sha256: "5bf37738940d37ed1a77873d520e9bd2e57d6356802d6274fa52ba23c6625263"
url: "https://pub.dev"
source: hosted
version: "0.0.2+3"
jni:
dependency: transitive
description:
Expand Down Expand Up @@ -1258,10 +1266,10 @@ packages:
dependency: "direct main"
description:
name: pdfrx
sha256: "3f9439e02f1bc82393225fe825867246b9a476ae5bf65b6a3e0a9ea4032aa8e9"
sha256: "9a0a9659ff2a0fd1f0057d66e936395f9d9d1043242e58f3f203134055cbe5bf"
url: "https://pub.dev"
source: hosted
version: "1.0.88"
version: "1.0.91"
pedometer:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1960,10 +1968,10 @@ packages:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.1.0"
web_socket:
dependency: transitive
description:
Expand Down
Loading

0 comments on commit 7d00d90

Please sign in to comment.