Skip to content

Commit 1e180eb

Browse files
author
Jon Petersson
committed
Add UI for creating and editing a custom list
1 parent ef86758 commit 1e180eb

19 files changed

+914
-26
lines changed

ios/MullvadSettings/CustomList.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import MullvadTypes
1212
public struct CustomList: Codable, Equatable {
1313
public let id: UUID
1414
public var name: String
15-
public var list: [RelayLocation] = []
16-
public init(id: UUID, name: String) {
15+
public var locations: [RelayLocation]
16+
17+
public init(id: UUID = UUID(), name: String, locations: [RelayLocation]) {
1718
self.id = id
1819
self.name = name
20+
self.locations = locations
1921
}
2022
}

ios/MullvadSettings/CustomListRepository.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ public struct CustomListRepository: CustomListRepositoryProtocol {
4141

4242
public init() {}
4343

44-
public func create(_ name: String) throws -> CustomList {
44+
public func create(_ name: String, locations: [RelayLocation]) throws -> CustomList {
4545
var lists = fetchAll()
4646
if lists.contains(where: { $0.name == name }) {
4747
throw CustomRelayListError.duplicateName
4848
} else {
49-
let item = CustomList(id: UUID(), name: name)
49+
let item = CustomList(id: UUID(), name: name, locations: locations)
5050
lists.append(item)
5151
try write(lists)
5252
return item

ios/MullvadSettings/CustomListRepositoryProtocol.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ public protocol CustomListRepositoryProtocol {
2828

2929
/// Create a custom list by unique name.
3030
/// - Parameter name: a custom list name.
31+
/// - Parameter locations: locations in a custom list.
3132
/// - Returns: a persistent custom list model upon success, otherwise throws `Error`.
32-
func create(_ name: String) throws -> CustomList
33+
func create(_ name: String, locations: [RelayLocation]) throws -> CustomList
3334

3435
/// Fetch all custom list.
3536
/// - Returns: all custom list model .

ios/MullvadVPN.xcodeproj/project.pbxproj

+57-1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,18 @@
518518
7A6000F92B6273A4001CF0D9 /* AccessMethodViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586C0D7B2B03BDD100E7CDD7 /* AccessMethodViewModel.swift */; };
519519
7A6000FC2B628DF6001CF0D9 /* ListCellContentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6000FB2B628DF6001CF0D9 /* ListCellContentConfiguration.swift */; };
520520
7A6000FE2B628E9F001CF0D9 /* ListCellContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6000FD2B628E9F001CF0D9 /* ListCellContentView.swift */; };
521+
7A6389DB2B7E3BD6008E77E1 /* CustomListCellConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389D22B7E3BD6008E77E1 /* CustomListCellConfiguration.swift */; };
522+
7A6389DC2B7E3BD6008E77E1 /* CustomListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389D32B7E3BD6008E77E1 /* CustomListViewModel.swift */; };
523+
7A6389DD2B7E3BD6008E77E1 /* CustomListDataSourceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389D42B7E3BD6008E77E1 /* CustomListDataSourceConfiguration.swift */; };
524+
7A6389DE2B7E3BD6008E77E1 /* CustomListItemIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389D52B7E3BD6008E77E1 /* CustomListItemIdentifier.swift */; };
525+
7A6389DF2B7E3BD6008E77E1 /* AddCustomListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389D72B7E3BD6008E77E1 /* AddCustomListCoordinator.swift */; };
526+
7A6389E12B7E3BD6008E77E1 /* CustomListSectionIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389D92B7E3BD6008E77E1 /* CustomListSectionIdentifier.swift */; };
527+
7A6389E22B7E3BD6008E77E1 /* CustomListInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389DA2B7E3BD6008E77E1 /* CustomListInteractor.swift */; };
528+
7A6389E52B7E4247008E77E1 /* EditCustomListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389E42B7E4247008E77E1 /* EditCustomListCoordinator.swift */; };
529+
7A6389E72B7E42BE008E77E1 /* CustomListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389E62B7E42BE008E77E1 /* CustomListViewController.swift */; };
530+
7A6389E92B7F8FE2008E77E1 /* CustomListValidationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389E82B7F8FE2008E77E1 /* CustomListValidationError.swift */; };
531+
7A6389EB2B7FAD7A008E77E1 /* SettingsValidationErrorContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389EA2B7FAD7A008E77E1 /* SettingsValidationErrorContentView.swift */; };
532+
7A6389ED2B7FADA1008E77E1 /* SettingsValidationErrorConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6389EC2B7FADA1008E77E1 /* SettingsValidationErrorConfiguration.swift */; };
521533
7A6B4F592AB8412E00123853 /* TunnelMonitorTimings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6B4F582AB8412E00123853 /* TunnelMonitorTimings.swift */; };
522534
7A6F2FA52AFA3CB2006D0856 /* AccountExpiryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6F2FA42AFA3CB2006D0856 /* AccountExpiryTests.swift */; };
523535
7A6F2FA72AFBB9AE006D0856 /* AccountExpiry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6F2FA62AFBB9AE006D0856 /* AccountExpiry.swift */; };
@@ -1727,6 +1739,18 @@
17271739
7A6000F52B60092F001CF0D9 /* AccessMethodViewModelEditing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessMethodViewModelEditing.swift; sourceTree = "<group>"; };
17281740
7A6000FB2B628DF6001CF0D9 /* ListCellContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCellContentConfiguration.swift; sourceTree = "<group>"; };
17291741
7A6000FD2B628E9F001CF0D9 /* ListCellContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCellContentView.swift; sourceTree = "<group>"; };
1742+
7A6389D22B7E3BD6008E77E1 /* CustomListCellConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListCellConfiguration.swift; sourceTree = "<group>"; };
1743+
7A6389D32B7E3BD6008E77E1 /* CustomListViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListViewModel.swift; sourceTree = "<group>"; };
1744+
7A6389D42B7E3BD6008E77E1 /* CustomListDataSourceConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListDataSourceConfiguration.swift; sourceTree = "<group>"; };
1745+
7A6389D52B7E3BD6008E77E1 /* CustomListItemIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListItemIdentifier.swift; sourceTree = "<group>"; };
1746+
7A6389D72B7E3BD6008E77E1 /* AddCustomListCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddCustomListCoordinator.swift; sourceTree = "<group>"; };
1747+
7A6389D92B7E3BD6008E77E1 /* CustomListSectionIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListSectionIdentifier.swift; sourceTree = "<group>"; };
1748+
7A6389DA2B7E3BD6008E77E1 /* CustomListInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomListInteractor.swift; sourceTree = "<group>"; };
1749+
7A6389E42B7E4247008E77E1 /* EditCustomListCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCustomListCoordinator.swift; sourceTree = "<group>"; };
1750+
7A6389E62B7E42BE008E77E1 /* CustomListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomListViewController.swift; sourceTree = "<group>"; };
1751+
7A6389E82B7F8FE2008E77E1 /* CustomListValidationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomListValidationError.swift; sourceTree = "<group>"; };
1752+
7A6389EA2B7FAD7A008E77E1 /* SettingsValidationErrorContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsValidationErrorContentView.swift; sourceTree = "<group>"; };
1753+
7A6389EC2B7FADA1008E77E1 /* SettingsValidationErrorConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsValidationErrorConfiguration.swift; sourceTree = "<group>"; };
17301754
7A6B4F582AB8412E00123853 /* TunnelMonitorTimings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelMonitorTimings.swift; sourceTree = "<group>"; };
17311755
7A6F2FA42AFA3CB2006D0856 /* AccountExpiryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiryTests.swift; sourceTree = "<group>"; };
17321756
7A6F2FA62AFBB9AE006D0856 /* AccountExpiry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiry.swift; sourceTree = "<group>"; };
@@ -3003,6 +3027,8 @@
30033027
58CAF9F22983D32200BE19F7 /* Coordinators */ = {
30043028
isa = PBXGroup;
30053029
children = (
3030+
7A6389D12B7E3BD6008E77E1 /* CustomLists */,
3031+
58EFC76F2AFB3FA800E9F4CB /* Settings */,
30063032
7A9CCCAF2A96302800DD6A34 /* AccountCoordinator.swift */,
30073033
7A9CCCAC2A96302800DD6A34 /* AccountDeletionCoordinator.swift */,
30083034
7A9CCCA32A96302700DD6A34 /* AddCreditSucceededCoordinator.swift */,
@@ -3018,7 +3044,6 @@
30183044
7A9CCCA52A96302700DD6A34 /* RevokedCoordinator.swift */,
30193045
7A9CCCB02A96302800DD6A34 /* SafariCoordinator.swift */,
30203046
7A9CCCA72A96302700DD6A34 /* SelectLocationCoordinator.swift */,
3021-
58EFC76F2AFB3FA800E9F4CB /* Settings */,
30223047
7A9CCCA62A96302700DD6A34 /* SetupAccountCompletedCoordinator.swift */,
30233048
7A9CCCA22A96302700DD6A34 /* TermsOfServiceCoordinator.swift */,
30243049
7A9CCCB22A96302800DD6A34 /* TunnelCoordinator.swift */,
@@ -3299,6 +3324,8 @@
32993324
7A5869A92B55516700640D27 /* IPOverride */,
33003325
58EFC7702AFB45E500E9F4CB /* SettingsChildCoordinator.swift */,
33013326
7A9CCCAD2A96302800DD6A34 /* SettingsCoordinator.swift */,
3327+
7A6389EC2B7FADA1008E77E1 /* SettingsValidationErrorConfiguration.swift */,
3328+
7A6389EA2B7FAD7A008E77E1 /* SettingsValidationErrorContentView.swift */,
33023329
);
33033330
path = Settings;
33043331
sourceTree = "<group>";
@@ -3381,6 +3408,23 @@
33813408
path = IPOverride;
33823409
sourceTree = "<group>";
33833410
};
3411+
7A6389D12B7E3BD6008E77E1 /* CustomLists */ = {
3412+
isa = PBXGroup;
3413+
children = (
3414+
7A6389D72B7E3BD6008E77E1 /* AddCustomListCoordinator.swift */,
3415+
7A6389D22B7E3BD6008E77E1 /* CustomListCellConfiguration.swift */,
3416+
7A6389D42B7E3BD6008E77E1 /* CustomListDataSourceConfiguration.swift */,
3417+
7A6389DA2B7E3BD6008E77E1 /* CustomListInteractor.swift */,
3418+
7A6389D52B7E3BD6008E77E1 /* CustomListItemIdentifier.swift */,
3419+
7A6389D92B7E3BD6008E77E1 /* CustomListSectionIdentifier.swift */,
3420+
7A6389E82B7F8FE2008E77E1 /* CustomListValidationError.swift */,
3421+
7A6389E62B7E42BE008E77E1 /* CustomListViewController.swift */,
3422+
7A6389D32B7E3BD6008E77E1 /* CustomListViewModel.swift */,
3423+
7A6389E42B7E4247008E77E1 /* EditCustomListCoordinator.swift */,
3424+
);
3425+
path = CustomLists;
3426+
sourceTree = "<group>";
3427+
};
33843428
7A83C3FC2A55B39500DFB83A /* TestPlans */ = {
33853429
isa = PBXGroup;
33863430
children = (
@@ -4908,6 +4952,7 @@
49084952
isa = PBXSourcesBuildPhase;
49094953
buildActionMask = 2147483647;
49104954
files = (
4955+
7A6389DC2B7E3BD6008E77E1 /* CustomListViewModel.swift in Sources */,
49114956
7A9CCCC42A96302800DD6A34 /* TunnelCoordinator.swift in Sources */,
49124957
5827B0A42B0F38FD00CCBBA1 /* EditAccessMethodInteractorProtocol.swift in Sources */,
49134958
586C0D852B03D31E00E7CDD7 /* SocksSectionHandler.swift in Sources */,
@@ -4956,6 +5001,7 @@
49565001
7A516C2E2B6D357500BBD33D /* URL+Scoping.swift in Sources */,
49575002
5878A27529093A310096FC88 /* StorePaymentEvent.swift in Sources */,
49585003
7A7AD28D29DC677800480EF1 /* FirstTimeLaunch.swift in Sources */,
5004+
7A6389EB2B7FAD7A008E77E1 /* SettingsValidationErrorContentView.swift in Sources */,
49595005
58B26E2A2943545A00D5980C /* NotificationManagerDelegate.swift in Sources */,
49605006
58A1AA8C23F5584C009F7EA6 /* ConnectionPanelView.swift in Sources */,
49615007
5878A27B2909649A0096FC88 /* CustomOverlayRenderer.swift in Sources */,
@@ -5018,6 +5064,7 @@
50185064
58293FB125124117005D0BB5 /* CustomTextField.swift in Sources */,
50195065
F09A29822A9F8AD200EA3B6F /* RedeemVoucherInteractor.swift in Sources */,
50205066
58138E61294871C600684F0C /* DeviceDataThrottling.swift in Sources */,
5067+
7A6389ED2B7FADA1008E77E1 /* SettingsValidationErrorConfiguration.swift in Sources */,
50215068
5878A279290954790096FC88 /* TunnelViewControllerInteractor.swift in Sources */,
50225069
7A818F1F29F0305800C7F0F4 /* RootConfiguration.swift in Sources */,
50235070
7A9CCCBF2A96302800DD6A34 /* SettingsCoordinator.swift in Sources */,
@@ -5050,6 +5097,7 @@
50505097
588527B4276B4F2F00BAA373 /* SetAccountOperation.swift in Sources */,
50515098
58FF9FE02B075ABC00E4C97D /* EditAccessMethodViewController.swift in Sources */,
50525099
F0DA87472A9CB9A2006044F1 /* AccountExpiryRow.swift in Sources */,
5100+
7A6389E92B7F8FE2008E77E1 /* CustomListValidationError.swift in Sources */,
50535101
585CA70F25F8C44600B47C62 /* UIMetrics.swift in Sources */,
50545102
E1187ABD289BBB850024E748 /* OutOfTimeContentView.swift in Sources */,
50555103
58CC40EF24A601900019D96E /* ObserverList.swift in Sources */,
@@ -5071,6 +5119,7 @@
50715119
58E25F812837BBBB002CFB2C /* SceneDelegate.swift in Sources */,
50725120
7A1A26492A29D48A00B978AA /* RelayFilterCellFactory.swift in Sources */,
50735121
5867771629097C5B006F721F /* ProductState.swift in Sources */,
5122+
7A6389DE2B7E3BD6008E77E1 /* CustomListItemIdentifier.swift in Sources */,
50745123
58C76A082A33850E00100D75 /* ApplicationTarget.swift in Sources */,
50755124
58CEB3042AFD36CE00E6E088 /* SwitchCellContentView.swift in Sources */,
50765125
F07BF2622A26279100042943 /* RedeemVoucherOperation.swift in Sources */,
@@ -5086,8 +5135,11 @@
50865135
7AF9BE8E2A331C7B00DBFEDB /* RelayFilterViewModel.swift in Sources */,
50875136
58F3C0A4249CB069003E76BE /* HeaderBarView.swift in Sources */,
50885137
5864AF0829C78849005B0CD9 /* CellFactoryProtocol.swift in Sources */,
5138+
7A6389E22B7E3BD6008E77E1 /* CustomListInteractor.swift in Sources */,
50895139
F07CFF2029F2720E008C0343 /* RegisteredDeviceInAppNotificationProvider.swift in Sources */,
5140+
7A6389E12B7E3BD6008E77E1 /* CustomListSectionIdentifier.swift in Sources */,
50905141
58CEB2F32AFD0BA100E6E088 /* TextCellContentView.swift in Sources */,
5142+
7A6389E72B7E42BE008E77E1 /* CustomListViewController.swift in Sources */,
50915143
586C0D7C2B03BDD100E7CDD7 /* AccessMethodViewModel.swift in Sources */,
50925144
587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */,
50935145
7A6F2FA72AFBB9AE006D0856 /* AccountExpiry.swift in Sources */,
@@ -5107,6 +5159,7 @@
51075159
5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */,
51085160
58B26E242943520C00D5980C /* NotificationProviderProtocol.swift in Sources */,
51095161
5877F94E2A0A59AA0052D9E9 /* NotificationResponse.swift in Sources */,
5162+
7A6389E52B7E4247008E77E1 /* EditCustomListCoordinator.swift in Sources */,
51105163
58677712290976FB006F721F /* SettingsInteractor.swift in Sources */,
51115164
58EF875D2B1638BF00C098B2 /* ProxyConfigurationTesterProtocol.swift in Sources */,
51125165
58CE5E66224146200008646E /* LoginViewController.swift in Sources */,
@@ -5167,6 +5220,7 @@
51675220
581DA2752A1E283E0046ED47 /* WgKeyRotation.swift in Sources */,
51685221
5827B0BB2B14A28300CCBBA1 /* MethodTestingStatusCellContentView.swift in Sources */,
51695222
7A83C4022A57FAA800DFB83A /* SettingsDNSInfoCell.swift in Sources */,
5223+
7A6389DF2B7E3BD6008E77E1 /* AddCustomListCoordinator.swift in Sources */,
51705224
586C0D952B03D92100E7CDD7 /* SocksItemIdentifier.swift in Sources */,
51715225
F0C6A8432AB08E54000777A8 /* RedeemVoucherViewConfiguration.swift in Sources */,
51725226
7AF10EB42ADE85BC00C090B9 /* RelayFilterCoordinator.swift in Sources */,
@@ -5203,6 +5257,7 @@
52035257
584D26C4270C855B004EA533 /* PreferencesDataSource.swift in Sources */,
52045258
F0D8825B2B04F53600D3EF9A /* OutgoingConnectionData.swift in Sources */,
52055259
7A6F2FAF2AFE36E7006D0856 /* PreferencesInfoButtonItem.swift in Sources */,
5260+
7A6389DD2B7E3BD6008E77E1 /* CustomListDataSourceConfiguration.swift in Sources */,
52065261
5827B0BF2B14B37D00CCBBA1 /* Publisher+PreviousValue.swift in Sources */,
52075262
7A9CCCB62A96302800DD6A34 /* OutOfTimeCoordinator.swift in Sources */,
52085263
5827B0AA2B0F4C9100CCBBA1 /* EditAccessMethodViewControllerDelegate.swift in Sources */,
@@ -5221,6 +5276,7 @@
52215276
7A21DACF2A30AA3700A787A9 /* UITextField+Appearance.swift in Sources */,
52225277
585B1FF02AB09F97008AD470 /* VPNConnectionProtocol.swift in Sources */,
52235278
58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */,
5279+
7A6389DB2B7E3BD6008E77E1 /* CustomListCellConfiguration.swift in Sources */,
52245280
F09A297C2A9F8A9B00EA3B6F /* VoucherTextField.swift in Sources */,
52255281
7A5869B72B56B41500640D27 /* IPOverrideTextViewController.swift in Sources */,
52265282
58ACF64B26553C3F00ACE4B7 /* SettingsSwitchCell.swift in Sources */,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// AddCustomListCoordinator.swift
3+
// MullvadVPN
4+
//
5+
// Created by Jon Petersson on 2024-02-14.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import Combine
10+
import MullvadSettings
11+
import Routing
12+
import UIKit
13+
14+
class AddCustomListCoordinator: Coordinator, Presentable, Presenting {
15+
let navigationController: UINavigationController
16+
let customListInteractor: CustomListInteractorProtocol
17+
18+
var presentedViewController: UIViewController {
19+
navigationController
20+
}
21+
22+
var didFinish: (() -> Void)?
23+
24+
init(
25+
navigationController: UINavigationController,
26+
customListInteractor: CustomListInteractorProtocol
27+
) {
28+
self.navigationController = navigationController
29+
self.customListInteractor = customListInteractor
30+
}
31+
32+
func start() {
33+
let subject = CurrentValueSubject<CustomListViewModel, Never>(
34+
CustomListViewModel(id: UUID(), name: "", locations: [], tableSections: [.name, .addLocations])
35+
)
36+
37+
let controller = CustomListViewController(
38+
interactor: customListInteractor,
39+
subject: subject,
40+
alertPresenter: AlertPresenter(context: self)
41+
)
42+
controller.delegate = self
43+
44+
controller.navigationItem.title = NSLocalizedString(
45+
"CUSTOM_LIST_NAVIGATION_EDIT_TITLE",
46+
tableName: "CustomLists",
47+
value: "New custom list",
48+
comment: ""
49+
)
50+
51+
controller.saveBarButton.title = NSLocalizedString(
52+
"CUSTOM_LIST_NAVIGATION_CREATE_BUTTON",
53+
tableName: "CustomLists",
54+
value: "Create",
55+
comment: ""
56+
)
57+
58+
navigationController.pushViewController(controller, animated: false)
59+
}
60+
}
61+
62+
extension AddCustomListCoordinator: CustomListViewControllerDelegate {
63+
func customListDidSave() {
64+
didFinish?()
65+
}
66+
67+
func customListDidDelete() {
68+
// No op.
69+
}
70+
71+
func showLocations() {
72+
// TODO: Show view controller for locations.
73+
}
74+
}

0 commit comments

Comments
 (0)