asturaphoenix / trip_planner_aquamarine Goto Github PK
View Code? Open in Web Editor NEWBASK Trip Planner cross-platform
License: MIT License
BASK Trip Planner cross-platform
License: MIT License
Port over the Measure Distance feature. This should be usable ad-hoc in addition to plotting new routes.
Only the tests directly under test
are run right now, with flutter test
. Run dart test
under server
, util
, latlng
, and wherever else.
The newly added files are auto-selected, but that may not be updating the selection indices for shift-select.
The plot panel could use a design pass. This panel manages track overlays. Currently, only GPS tracks from GPX files are supported. Eventually, it should also support tracks from Strava and plotting new routes. Paddle tracking will probably have its own button in the main app bar, as it warrants more prominent positioning than within the Plot tab.
While currently picking GPX files is the only supported method, eventually it may not be commonly used as it's not the most convenient.
Tracks from Strava would be added by authenticating with Strava once and then syncing automatically. Strava branding guidelines require that the authentication be triggered from a button that looks like this:
Eventually we'll probably expect list items to be sorted reverse-chronologically, like an activity feed. Whether this is by start or end time remains to be decided. Newly plotted routes could be sorted first; eventually they'll probably have times associated with them for tide/current planning. (However, some GPX files do not contain time information.)
The current layout, at high level a list, button, and graph, is okay for desktop:
but is a little awkward on mobile between using too much space and the list expanding from the middle of the panel when the sheet is expanded:
The graph is hidden when no tracks are selected:
Landscape:
I suspect that instead, we'll want to have the list at the bottom so that it expands gracefully to reveal more items as the bottom sheet is dragged up. This would mean putting the graph first and figuring something different out for the button.
One design idiom we could apply is a Floating Action Button to add GPS overlays. This FAB would probably have to emit options like "Connect with Strava" or "Plot new route" in addition to "Add GPX". However, once Strava is connected, the number of options would drop to 2, which is below the recommended 3 for a FAB that emits options. Another consideration is that for users who never intend to Connect with Strava, we might not want to shove Strava down their throats every time they try to plot a route.
Having the FAB in its canonical bottom-right position puts it a bit too far from the list on desktop when the list doesn't have much content:
This could be addressed by putting it towards the end of the content rather than the end of the outer container (shrinking the scaffold), but is still strange if we expect list items to be sorted reverse-chronologically like a feed, where new additions would likely be at the top rather than at the bottom.
Docking the FAB onto the top of the list looks okay when the graph is shown:
but would need special handling when it is hidden:
Docking the FAB onto the border between the tab and the panel also has issues.
In the desktop layout, it encroaches too far into the tab bar and covers list UI when the graph is hidden (possibly addressable by making it a mini FAB):
and appears too far removed from the list when the graph is shown:
Additionally, when the bottom sheet is collapsed on mobile, the button is awkwardly still half on screen (addressable by hiding it for this case):
Sometimes the UI doesn't update at all. This is probably a regression in the flutter_map
migration.
Especially for things like the readme.
We should add a panel for layers, for fine-tuned configuration of:
It's probably worth keeping this separate from the Plot panel.
This was a flake on the emulator in CI:
03:38 +3: with orientation cycle map lock modes
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test (but after the test had completed):
Bad state: No element
When the exception was thrown, this was the stack:
#0 ListMixin.firstWhere (dart:collection/list.dart:168:5)
#1 CompassState.initState.<anonymous closure> (package:trip_planner_aquamarine/widgets/compass.dart:223:54)
<asynchronous suspension>
════════════════════════════════════════════════════════════════════════════════════════════════════
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test (but after the test had completed):
Bad state: No element
When the exception was thrown, this was the stack:
#0 ListMixin.firstWhere (dart:collection/list.dart:168:5)
#1 CompassState.initState.<anonymous closure> (package:trip_planner_aquamarine/widgets/compass.dart:223:54)
<asynchronous suspension>
════════════════════════════════════════════════════════════════════════════════════════════════════
04:08 +3: with real permissions permissions requests and app lifecycles
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following PatrolActionException was thrown running a test:
Patrol action failed: grantPermissionWhenInUse() failed with code NOT_FOUND (selector button to
allow permission while using found nothing)
When the exception was thrown, this was the stack:
#0 NativeAutomator._wrapRequest (package:patrol/src/native/native_automator.dart:168:7)
<asynchronous suspension>
#1 NativeAutomator.grantPermissionWhenInUse (package:patrol/src/native/native_automator.dart:531:5)
<asynchronous suspension>
#2 main.<anonymous closure>.<anonymous closure> (file:///home/runner/work/trip_planner_aquamarine/trip_planner_aquamarine/trip_planner_aquamarine/integration_test/native_test.dart:218:7)
<asynchronous suspension>
#3 patrolTest.<anonymous closure> (package:patrol/src/common.dart:91:7)
<asynchronous suspension>
#4 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:170:15)
<asynchronous suspension>
#5 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:934:5)
<asynchronous suspension>
The test description was:
permissions requests and app lifecycles
════════════════════════════════════════════════════════════════════════════════════════════════════
04:08 +3: with real permissions permissions requests and app lifecycles [E]
Test failed. See exception logs above.
The test description was: permissions requests and app lifecycles
04:08 +3 -1: (tearDownAll)
04:08 +4 -1: Some tests failed.
The code in question:
cameraController = CameraController(
(() async => (await camera.availableCameras()).firstWhere(
(c) => c.lensDirection == camera.CameraLensDirection.back,
))(),
camera.ResolutionPreset.max,
);
BS emulators aside, we shouldn't crash if there's no camera.
E.g. https://www.bask.org/trip_planner/5.62/?m=x228
Currently on Android this gets stuck on a blank page.
On Android native.
This is a third-party widget, but we should debug the performance issue.
It's not issuing another network request, but it's definitely decoding.
Although we cache encoded tile data for offline use, our naive web plugin implementation doesn't yet cache decoded images on its side. This can improve performance while zooming in and out or panning over a common area.
Right now the plot tab defaults to tide/current stations first. This may not be necessary.
Right now if camera permissions are denied the compass throws an error and shows a spinner forever where the camera display would be. Instead, catch the exception and hide the spinner. If we have a setting in the app to enable/disable the camera, possibly disable it.
This might be a challenge to test, as the camera permissions happen natively. Our best bet might be to mock out the permission failure in a widget test.
The default behavior in Android Maps is to not be a live view. We may be able to get around this by recreating the tooltip whenever there's an update.
We should keep the tide graph alive or else put the time window state in the main app.
It would be valuable to have a drybag-searchable list (menu-based rather than keyboard-based) of locations from Where the heck is Collinsville along with buoy numbers, so that when VTS says the Knossos is passing Oakland Inner Harbor buoy 1, we don't have to guess at where that is.
This could also be handy in reverse, to list nearby waypoints, so we have something more helpful than lat/lng for our own reporting. e.g. "We're holding .25 nm south of Northship Channel buoy 1."
After successfully resolving the redirect to the classic Trip Planner, the URL is cached, but not cleared in the event of a subsequent error. This may mean that if the classic Trip Planner version changes, an Aquamarine restart would be required to issue any new requests.
Right now, time scrubbing rebuilds the map, which diffs all 1300 markers.
Showing the mobile keyboard results in various overflows, which are unnecessary in portrait and break the dialog layout in landscape.
Possible AIS provider: https://aishub.net, but they require us to have our own repeater anyway. There are local stations listed there that we could try to contact.
We might also ask if San Francisco VTS is willing to share in the public interest.
There's also a free API that seems to be in development but I can't tell how legitimate it is so I'll avoid linking it for now.
Magnetic variation is coded to only update if the device moves out of a certain area. However, the magnetic variation varies faster than the current threshold, which is noticeable in the display with resolution in minutes. Between the North Bay and South Bay, the magnetic declination varies from 13°10' to 13°0'.
This exception is eventually caught, but we probably don't register an error handler early enough for Dart to consider the error caught. This is probably a future in a cache. The traces weren't particularly useful; one instance was an http.ClientException
from interleave2x32
.
In the error logs:
[2023-07-30 01:40:03.554665Z] WARNING AquamarineServer: Failed to fetch f025.20230729.t21z
Connection closed while receiving data
#0 IOClient.send.<anonymous closure> (package:http/src/io_client.dart:82:13)
#1 Stream.handleError.<anonymous closure> (dart:async/stream.dart:923:16)
This probably only impacts running in debug mode, where the VM stops on uncaught asynchronous exceptions.
We should graph OFS current model data similar to the way we graph xtide predictions. Ideally we'd abstract both out as current models to facilitate the inclusion of future current models.
The graphing tech itself might have to be different as we're leveraging xtide's built-in graphing via the classic trip planner. We are integrated with a graphing library for GPX speed plots that we might be able to use.
It could be nice to overlay these graphs, or show them side-by-side, or both. This panel could include a facility to select the current model, linked to the Layers panel (#53).
Constant order results in unintuitive selection behavior in the Details tab since you probably want to select a destination but the touch targets for tide stations are in front.
Uncaught ImageCodecException: Failed to decode image data.
Image source: encoded image bytes
Likely from bad cached data.
This is a bit of a heavy ask, but it's probably what users would expect, and there shouldn't be a reason we can't.
There are several options, including porting xtide to dart (possibly based off a JS port) or wrapping an Android/iOS port.
Right now, info windows are constrained to like a width of 1024, which can result in some truly long single-line station name info windows. Let's constrain it smaller, possibly informed by screen/widget size.
We're implementing clickable polygons ourselves, but when we insert a polyline layer, it breaks our polygon clickability.
XHR doesn't support response streaming, which makes for very poor currents performance. fetch_client is a possible workaround.
Initialization by location
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.