mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-23 22:53:43 +00:00
[ios] implement TrackRecording place page
1. add an new screen (layout) 2. add TR icon for the bottom tabbar 3. share current location from the TR PP 4. refactor TR manager to properly handle state updates and pass them to the LiveActivityManager and PlacePage 5. add init/update with TrackInfo/EleInfo methods to the PlacePageData and PlacePagePreviewData to update the PP state Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
This commit is contained in:
committed by
Yannik Bloscheck
parent
5d0b8f1c04
commit
b79724f248
@@ -4,9 +4,15 @@
|
||||
|
||||
@class MapViewController;
|
||||
@class BottomTabBarViewController;
|
||||
@class TrackRecordingViewController;
|
||||
@class TrackRecordingButtonViewController;
|
||||
@class SearchQuery;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TrackRecordingButtonState) {
|
||||
TrackRecordingButtonStateHidden,
|
||||
TrackRecordingButtonStateVisible,
|
||||
TrackRecordingButtonStateClosed,
|
||||
};
|
||||
|
||||
@protocol MWMFeatureHolder;
|
||||
|
||||
@interface MWMMapViewControlsManager : NSObject
|
||||
@@ -21,7 +27,7 @@
|
||||
@property(nonatomic) MWMBottomMenuState menuRestoreState;
|
||||
@property(nonatomic) BOOL isDirectionViewHidden;
|
||||
@property(nonatomic) BottomTabBarViewController * tabBarController;
|
||||
@property(nonatomic) TrackRecordingViewController * trackRecordingButton;
|
||||
@property(nonatomic) TrackRecordingButtonViewController * trackRecordingButton;
|
||||
|
||||
- (instancetype)init __attribute__((unavailable("init is not available")));
|
||||
- (instancetype)initWithParentController:(MapViewController *)controller;
|
||||
@@ -35,6 +41,8 @@
|
||||
- (void)viewWillTransitionToSize:(CGSize)size
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
|
||||
|
||||
- (void)setTrackRecordingButtonState:(TrackRecordingButtonState)state;
|
||||
|
||||
#pragma mark - MWMNavigationDashboardManager
|
||||
|
||||
- (void)onRoutePrepare;
|
||||
|
||||
@@ -28,15 +28,15 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
@interface MWMMapViewControlsManager () <BottomMenuDelegate>
|
||||
|
||||
@property(nonatomic) MWMSideButtons *sideButtons;
|
||||
@property(nonatomic) MWMTrafficButtonViewController *trafficButton;
|
||||
@property(nonatomic) UIButton *promoButton;
|
||||
@property(nonatomic) UIViewController *menuController;
|
||||
@property(nonatomic) MWMSideButtons * sideButtons;
|
||||
@property(nonatomic) MWMTrafficButtonViewController * trafficButton;
|
||||
@property(nonatomic) UIButton * promoButton;
|
||||
@property(nonatomic) UIViewController * menuController;
|
||||
@property(nonatomic) id<MWMPlacePageProtocol> placePageManager;
|
||||
@property(nonatomic) MWMNavigationDashboardManager *navigationManager;
|
||||
@property(nonatomic) SearchOnMapManager *searchManager;
|
||||
@property(nonatomic) MWMNavigationDashboardManager * navigationManager;
|
||||
@property(nonatomic) SearchOnMapManager * searchManager;
|
||||
|
||||
@property(weak, nonatomic) MapViewController *ownerController;
|
||||
@property(weak, nonatomic) MapViewController * ownerController;
|
||||
|
||||
@property(nonatomic) BOOL disableStandbyOnRouteFollowing;
|
||||
@property(nonatomic) BOOL isAddingPlace;
|
||||
@@ -63,17 +63,10 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
self.menuState = MWMBottomMenuStateInactive;
|
||||
self.menuRestoreState = MWMBottomMenuStateInactive;
|
||||
self.isAddingPlace = NO;
|
||||
[TrackRecordingManager.shared addObserver:self recordingIsActiveDidChangeHandler:^(TrackRecordingState state, TrackInfo * trackInfo) {
|
||||
[self setTrackRecordingButtonHidden:state == TrackRecordingStateInactive];
|
||||
}];
|
||||
self.searchManager = controller.searchManager;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[TrackRecordingManager.shared removeObserver:self];
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
BOOL const isNavigationUnderStatusBar = self.navigationManager.state != MWMNavigationDashboardStateHidden &&
|
||||
self.navigationManager.state != MWMNavigationDashboardStateNavigation;
|
||||
@@ -280,17 +273,15 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
self.trafficButton.hidden = self.hidden || _trafficButtonHidden;
|
||||
}
|
||||
|
||||
- (void)setTrackRecordingButtonHidden:(BOOL)trackRecordingButtonHidden {
|
||||
if (trackRecordingButtonHidden && _trackRecordingButton) {
|
||||
[self.trackRecordingButton closeWithCompletion:^{
|
||||
[MWMMapWidgetsHelper updateLayoutForAvailableArea];
|
||||
}];
|
||||
_trackRecordingButton = nil;
|
||||
- (void)setTrackRecordingButtonState:(TrackRecordingButtonState)state {
|
||||
if (!_trackRecordingButton) {
|
||||
_trackRecordingButton = [[TrackRecordingButtonViewController alloc] init];
|
||||
}
|
||||
else if (!trackRecordingButtonHidden && !_trackRecordingButton) {
|
||||
_trackRecordingButton = [[TrackRecordingViewController alloc] init];
|
||||
[self.trackRecordingButton setState:state completion:^{
|
||||
[MWMMapWidgetsHelper updateLayoutForAvailableArea];
|
||||
}
|
||||
}];
|
||||
if (state == TrackRecordingButtonStateClosed)
|
||||
_trackRecordingButton = nil;
|
||||
}
|
||||
|
||||
- (void)setMenuState:(MWMBottomMenuState)menuState {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
final class TrackRecordingViewController: MWMViewController {
|
||||
final class TrackRecordingButtonViewController: MWMViewController {
|
||||
|
||||
private enum Constants {
|
||||
static let buttonDiameter = CGFloat(48)
|
||||
@@ -13,6 +13,7 @@ final class TrackRecordingViewController: MWMViewController {
|
||||
private var blinkingTimer: Timer?
|
||||
private var topConstraint = NSLayoutConstraint()
|
||||
private var trailingConstraint = NSLayoutConstraint()
|
||||
private var state: TrackRecordingButtonState = .hidden
|
||||
|
||||
private static var availableArea: CGRect = .zero
|
||||
private static var topConstraintValue: CGFloat {
|
||||
@@ -38,31 +39,29 @@ final class TrackRecordingViewController: MWMViewController {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
UIView.transition(with: self.view,
|
||||
duration: kDefaultAnimationDuration,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: {
|
||||
self.button.isHidden = false
|
||||
})
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// async is for smoother appearance
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + kDefaultAnimationDuration) {
|
||||
self.setState(self.state, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Public methods
|
||||
|
||||
@objc
|
||||
func close(completion: @escaping (() -> Void)) {
|
||||
stopTimer()
|
||||
UIView.transition(with: self.view,
|
||||
duration: kDefaultAnimationDuration,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: {
|
||||
self.button.isHidden = true
|
||||
}, completion: { _ in
|
||||
self.removeFromParent()
|
||||
self.view.removeFromSuperview()
|
||||
completion()
|
||||
})
|
||||
func setState(_ state: TrackRecordingButtonState, completion: (() -> Void)?) {
|
||||
self.state = state
|
||||
switch state {
|
||||
case .visible:
|
||||
setHidden(false, completion: nil)
|
||||
case .hidden:
|
||||
setHidden(true, completion: completion)
|
||||
case .closed:
|
||||
close(completion: completion)
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private methods
|
||||
@@ -75,7 +74,7 @@ final class TrackRecordingViewController: MWMViewController {
|
||||
button.tintColor = Constants.color.darker
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
button.setImage(UIImage(resource: .icMenuBookmarkTrackRecording), for: .normal)
|
||||
button.addTarget(self, action: #selector(onTrackRecordingButtonPressed), for: .touchUpInside)
|
||||
button.addTarget(self, action: #selector(didTap), for: .touchUpInside)
|
||||
button.isHidden = true
|
||||
}
|
||||
|
||||
@@ -97,7 +96,7 @@ final class TrackRecordingViewController: MWMViewController {
|
||||
}
|
||||
|
||||
private func updateLayout() {
|
||||
guard let superview = self.view.superview else { return }
|
||||
guard let superview = view.superview else { return }
|
||||
superview.animateConstraints {
|
||||
self.topConstraint.constant = Self.topConstraintValue
|
||||
self.trailingConstraint.constant = Self.trailingConstraintValue
|
||||
@@ -123,23 +122,39 @@ final class TrackRecordingViewController: MWMViewController {
|
||||
blinkingTimer = nil
|
||||
}
|
||||
|
||||
private func setHidden(_ hidden: Bool, completion: (() -> Void)?) {
|
||||
UIView.transition(with: self.view,
|
||||
duration: kDefaultAnimationDuration,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: {
|
||||
self.button.isHidden = hidden
|
||||
}) { _ in
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
private func close(completion: (() -> Void)?) {
|
||||
stopTimer()
|
||||
setHidden(true) { [weak self] in
|
||||
guard let self else { return }
|
||||
self.removeFromParent()
|
||||
self.view.removeFromSuperview()
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
static func updateAvailableArea(_ frame: CGRect) {
|
||||
availableArea = frame
|
||||
guard let controller = MapViewController.shared()?.controlsManager.trackRecordingButton else { return }
|
||||
guard let button = MapViewController.shared()?.controlsManager.trackRecordingButton else { return }
|
||||
DispatchQueue.main.async {
|
||||
controller.updateLayout()
|
||||
button.updateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc
|
||||
private func onTrackRecordingButtonPressed(_ sender: Any) {
|
||||
switch trackRecordingManager.recordingState {
|
||||
case .inactive:
|
||||
trackRecordingManager.processAction(.start)
|
||||
case .active:
|
||||
trackRecordingManager.processAction(.stop)
|
||||
}
|
||||
private func didTap(_ sender: Any) {
|
||||
MapViewController.shared()?.showTrackRecordingPlacePage()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user