Skip to content

Commit

Permalink
Merge pull request #130 from Myzel394/display-own-location
Browse files Browse the repository at this point in the history
Display own location
  • Loading branch information
Myzel394 authored Oct 16, 2023
2 parents 146f111 + 0c41598 commit 75de7b2
Show file tree
Hide file tree
Showing 28 changed files with 1,373 additions and 602 deletions.
27 changes: 27 additions & 0 deletions lib/App.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ import 'package:locus/widgets/DismissKeyboard.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:provider/provider.dart';

import 'app_wrappers/CheckViewAlarmsLive.dart';
import 'app_wrappers/HandleNotifications.dart';
import 'app_wrappers/InitCurrentLocationFromSettings.dart';
import 'app_wrappers/ManageQuickActions.dart';
import 'app_wrappers/PublishTaskPositionsOnUpdate.dart';
import 'app_wrappers/RegisterBackgroundListeners.dart';
import 'app_wrappers/ShowUpdateDialog.dart';
import 'app_wrappers/UniLinksHandler.dart';
import 'app_wrappers/UpdateLastLocationToSettings.dart';
import 'app_wrappers/UpdateLocaleToSettings.dart';
import 'app_wrappers/UpdateLocationHistory.dart';
import 'constants/themes.dart';

ColorScheme createColorScheme(
Expand Down Expand Up @@ -184,6 +195,22 @@ class App extends StatelessWidget {
),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
builder: (context, child) => Stack(
children: [
const UpdateLocationHistory(),
const UniLinksHandler(),
const UpdateLastLocationToSettings(),
const RegisterBackgroundListeners(),
const UpdateLocaleToSettings(),
const HandleNotifications(),
const CheckViewAlarmsLive(),
const ManageQuickActions(),
const InitCurrentLocationFromSettings(),
const ShowUpdateDialog(),
const PublishTaskPositionsOnUpdate(),
if (child != null) child,
],
),
onGenerateRoute: (routeSettings) {
final screen = (() {
if (settings.getRequireBiometricAuthenticationOnStart()) {
Expand Down
56 changes: 56 additions & 0 deletions lib/app_wrappers/CheckViewAlarmsLive.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:locus/services/current_location_service.dart';
import 'package:locus/services/location_point_service.dart';
import 'package:locus/services/manager_service/helpers.dart';
import 'package:locus/services/view_service/index.dart';
import 'package:provider/provider.dart';

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

/// Checks view alarms while the app is in use
class CheckViewAlarmsLive extends StatefulWidget {
const CheckViewAlarmsLive({super.key});

@override
State<CheckViewAlarmsLive> createState() => _CheckViewAlarmsLiveState();
}

class _CheckViewAlarmsLiveState extends State<CheckViewAlarmsLive> {
late final StreamSubscription<Position> _subscription;

@override
void initState() {
super.initState();

final currentLocation = context.read<CurrentLocationService>();
_subscription = currentLocation.stream.listen((position) async {
final l10n = AppLocalizations.of(context);
final viewService = context.read<ViewService>();
final userLocation = await LocationPointService.fromPosition(position);

if (!mounted) {
return;
}

checkViewAlarms(
l10n: l10n,
viewService: viewService,
userLocation: userLocation,
);
});
}

@override
void dispose() {
_subscription.cancel();
super.dispose();
}

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
98 changes: 98 additions & 0 deletions lib/app_wrappers/HandleNotifications.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_logs/flutter_logs.dart';
import 'package:locus/constants/notifications.dart';
import 'package:locus/constants/values.dart';
import 'package:locus/main.dart';
import 'package:locus/screens/ViewDetailsScreen.dart';
import 'package:locus/services/view_service/index.dart';
import 'package:locus/utils/PageRoute.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';

class HandleNotifications extends StatefulWidget {
const HandleNotifications({super.key});

@override
State<HandleNotifications> createState() => _HandleNotificationsState();
}

class _HandleNotificationsState extends State<HandleNotifications> {
late final StreamSubscription<NotificationResponse> _subscription;

@override
void initState() {
super.initState();
_subscription =
selectedNotificationsStream.stream.listen(_handleNotification);
}

@override
void dispose() {
_subscription.cancel();

super.dispose();
}

void _handleNotification(final NotificationResponse notification) {
FlutterLogs.logInfo(
LOG_TAG,
"Notification",
"Notification received: ${notification.payload}",
);

if (notification.payload == null) {
FlutterLogs.logWarn(
LOG_TAG,
"Notification",
"----> but no payload, so ignoring.",
);
return;
}

try {
final data = jsonDecode(notification.payload!);
final type = NotificationActionType.values[data["type"]];

FlutterLogs.logInfo(
LOG_TAG,
"Notification",
"Type is $type."
);

switch (type) {
case NotificationActionType.openTaskView:
final viewService = context.read<ViewService>();

Navigator.of(context).push(
NativePageRoute(
context: context,
builder: (_) =>
ViewDetailsScreen(
view: viewService.getViewById(data["taskViewID"]),
),
),
);
break;
case NotificationActionType.openPermissionsSettings:
openAppSettings();

break;
}
} catch (error) {
FlutterLogs.logError(
LOG_TAG,
"Notification",
"Error handling notification: $error",
);
}
}

@override
Widget build(BuildContext context) {
return const SizedBox.shrink();
}
}
45 changes: 45 additions & 0 deletions lib/app_wrappers/InitCurrentLocationFromSettings.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:locus/services/current_location_service.dart';
import 'package:locus/services/settings_service/SettingsMapLocation.dart';
import 'package:locus/services/settings_service/index.dart';
import 'package:provider/provider.dart';

class InitCurrentLocationFromSettings extends StatefulWidget {
const InitCurrentLocationFromSettings({super.key});

@override
State<InitCurrentLocationFromSettings> createState() =>
_InitCurrentLocationFromSettingsState();
}

class _InitCurrentLocationFromSettingsState
extends State<InitCurrentLocationFromSettings> {
late final CurrentLocationService _currentLocation;

@override
void initState() {
super.initState();

_currentLocation = context.read<CurrentLocationService>();

WidgetsBinding.instance.addPostFrameCallback((_) {
final settings = context.read<SettingsService>();
final lastLocation = settings.getLastMapLocation();

if (lastLocation != null) {
_setLocation(lastLocation);
}
});
}

void _setLocation(final SettingsLastMapLocation rawLocation) {
final position = rawLocation.asPosition();

_currentLocation.updateCurrentPosition(position);
}

@override
Widget build(BuildContext context) {
return const SizedBox.shrink();
}
}
10 changes: 10 additions & 0 deletions lib/app_wrappers/InitLocationFromSettings.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';

class InitLocationFromSettings extends StatelessWidget {
const InitLocationFromSettings({super.key});

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
133 changes: 133 additions & 0 deletions lib/app_wrappers/ManageQuickActions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_logs/flutter_logs.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:locus/constants/values.dart';
import 'package:locus/screens/ShortcutScreen.dart';
import 'package:locus/services/settings_service/index.dart';
import 'package:locus/utils/PageRoute.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:provider/provider.dart';
import 'package:quick_actions/quick_actions.dart';

enum ShortcutType {
createOneHour,
shareNow,
stopAllTasks,
}

const actions = QuickActions();

const SHORTCUT_TYPE_ICON_MAP = {
ShortcutType.createOneHour: Icons.timelapse_rounded,
ShortcutType.shareNow: Icons.location_on,
ShortcutType.stopAllTasks: Icons.stop_circle_rounded,
};

class ManageQuickActions extends StatefulWidget {
const ManageQuickActions({super.key});

@override
State<ManageQuickActions> createState() => _ManageQuickActionsState();
}

class _ManageQuickActionsState extends State<ManageQuickActions> {
@override
void initState() {
super.initState();

WidgetsBinding.instance.addPostFrameCallback((_) {
final settings = context.read<SettingsService>();

if (settings.userHasSeenWelcomeScreen) {
_registerActions();
} else {
_removeActions();
}
});
}

void _registerActions() {
final l10n = AppLocalizations.of(context);

FlutterLogs.logInfo(
LOG_TAG,
"Quick Actions",
"Initializing quick actions...",
);

actions.initialize((type) async {
FlutterLogs.logInfo(
LOG_TAG, "Quick Actions", "Quick action $type triggered.");

if (isCupertino(context)) {
showCupertinoModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (_) => ShortcutScreen(
type: ShortcutType.values.firstWhere(
(element) => element.name == type,
),
),
);
} else {
Navigator.push(
context,
NativePageRoute(
context: context,
builder: (_) => ShortcutScreen(
type: ShortcutType.values.firstWhere(
(element) => element.name == type,
),
),
),
);
}
});

actions.setShortcutItems([
ShortcutItem(
type: ShortcutType.createOneHour.name,
localizedTitle: l10n.quickActions_createOneHour,
icon: "ic_quick_actions_create_one_hour_task",
),
ShortcutItem(
type: ShortcutType.shareNow.name,
localizedTitle: l10n.quickActions_shareNow,
icon: "ic_quick_actions_share_now",
),
ShortcutItem(
type: ShortcutType.stopAllTasks.name,
localizedTitle: l10n.quickActions_stopTasks,
icon: "ic_quick_actions_stop_all_tasks",
),
]);

FlutterLogs.logInfo(
LOG_TAG,
"Quick Actions",
"Quick actions initialized successfully!",
);
}

void _removeActions() {
FlutterLogs.logInfo(
LOG_TAG,
"Quick Actions",
"Removing quick actions...",
);

actions.clearShortcutItems();

FlutterLogs.logInfo(
LOG_TAG,
"Quick Actions",
"Quick actions removed successfully!",
);
}

@override
Widget build(BuildContext context) {
return const SizedBox.shrink();
}
}
Loading

0 comments on commit 75de7b2

Please sign in to comment.