Compare commits
2 commits
iOS-17-Upd
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02a0f52c0c | ||
|
|
bbf94b1b34 |
80 changed files with 1299 additions and 978 deletions
|
|
@ -98,7 +98,7 @@ public class FileTransferClient {
|
|||
// Set current peripheral
|
||||
self.blePeripheral = blePeripheral
|
||||
|
||||
// Setup servic*es
|
||||
// Setup services
|
||||
let servicesGroup = DispatchGroup()
|
||||
|
||||
var error: Error? = nil
|
||||
|
|
|
|||
|
|
@ -3,19 +3,19 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objectVersion = 52;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
D505B99C2755323C00386E9F /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D505B99B2755323C00386E9F /* NetworkMonitor.swift */; };
|
||||
D505B99E2756894300386E9F /* ViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D505B99D2756894300386E9F /* ViewModifier.swift */; };
|
||||
D50887632A2E35510002B798 /* Wifi_ifaddrs.m in Sources */ = {isa = PBXBuildFile; fileRef = D50887622A2E35510002B798 /* Wifi_ifaddrs.m */; };
|
||||
D517F68126C5771D002996E8 /* FillerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D517F68026C5771D002996E8 /* FillerView.swift */; };
|
||||
D5199A2F28DD16F100ACC34C /* BleContentTransfer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5199A2E28DD16F100ACC34C /* BleContentTransfer.swift */; };
|
||||
D51D1413293A53BD0028AEDD /* WifiCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51D1412293A53BD0028AEDD /* WifiCellViewModel.swift */; };
|
||||
D520D69029D4C9380022048D /* WifiServiceCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D520D68F29D4C9380022048D /* WifiServiceCellView.swift */; };
|
||||
D520D69229D4C9900022048D /* WifiServiceCellSubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D520D69129D4C9900022048D /* WifiServiceCellSubView.swift */; };
|
||||
D5267411292E902700D4C79E /* Networking.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5267410292E902700D4C79E /* Networking.swift */; };
|
||||
D5269C00291960A300C0CE4B /* WifiSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5269BFF291960A300C0CE4B /* WifiSelection.swift */; };
|
||||
D5269C02291997DE00C0CE4B /* WifiServiceCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5269C01291997DE00C0CE4B /* WifiServiceCellView.swift */; };
|
||||
D5269C042919985400C0CE4B /* WifiServiceCellSubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5269C032919985400C0CE4B /* WifiServiceCellSubView.swift */; };
|
||||
D5269C08291AB75800C0CE4B /* WifiPairingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5269C07291AB75800C0CE4B /* WifiPairingView.swift */; };
|
||||
D52A926D29071DF400973B6B /* SelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52A926C29071DF400973B6B /* SelectionView.swift */; };
|
||||
D52A926F29078E0A00973B6B /* WifiServiceSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52A926E29078E0A00973B6B /* WifiServiceSelectionView.swift */; };
|
||||
|
|
@ -68,6 +68,7 @@
|
|||
D58D887B26CC02B60085604A /* OnboardingViewPure.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58D887A26CC02B60085604A /* OnboardingViewPure.swift */; };
|
||||
D58E1C8828A2B10B00AB683E /* WifiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58E1C8728A2B10B00AB683E /* WifiView.swift */; };
|
||||
D58E1C8A28A2B15E00AB683E /* WifiViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58E1C8928A2B15E00AB683E /* WifiViewModel.swift */; };
|
||||
D58E1C8D28A2B32C00AB683E /* Wifi_ifaddrs.m in Sources */ = {isa = PBXBuildFile; fileRef = D58E1C8C28A2B32C00AB683E /* Wifi_ifaddrs.m */; };
|
||||
D58E1C8F28A30A5300AB683E /* WifiNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58E1C8E28A30A5300AB683E /* WifiNetworkService.swift */; };
|
||||
D595FC2E2812C23D00569D8C /* Image Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D595FC2D2812C23D00569D8C /* Image Extension.swift */; };
|
||||
D59DFD8F268A4A4D001737F6 /* BTConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59DFD8E268A4A4D001737F6 /* BTConnectionView.swift */; };
|
||||
|
|
@ -83,8 +84,6 @@
|
|||
D5BA1F7F28B66F280012FC62 /* WifiServiceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BA1F7E28B66F280012FC62 /* WifiServiceManager.swift */; };
|
||||
D5BA1F8128B66F920012FC62 /* CircuitPythonService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BA1F8028B66F920012FC62 /* CircuitPythonService.swift */; };
|
||||
D5BA1F8328B68ED40012FC62 /* NetworkPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BA1F8228B68ED40012FC62 /* NetworkPeripheral.swift */; };
|
||||
D5BBD12C2A1538C100961B68 /* BoardDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BBD12B2A1538C100961B68 /* BoardDataProvider.swift */; };
|
||||
D5BBD12E2A1C6AB300961B68 /* BleBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BBD12D2A1C6AB300961B68 /* BleBannerView.swift */; };
|
||||
D5C474AC27E174A5002DD160 /* WebView Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C474AB27E174A5002DD160 /* WebView Content.swift */; };
|
||||
D5C474C827E39FD7002DD160 /* ReadexPro-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D5C474C627E39FC8002DD160 /* ReadexPro-Medium.ttf */; };
|
||||
D5C474C927E39FDA002DD160 /* ReadexPro-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D5C474C727E39FC8002DD160 /* ReadexPro-Regular.ttf */; };
|
||||
|
|
@ -117,14 +116,13 @@
|
|||
D50237E3280994F900F1EE8A /* PyLeap.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = PyLeap.entitlements; path = "../../../../Desktop/Copy Of PyLeap Entitlement/PyLeap.entitlements"; sourceTree = "<group>"; };
|
||||
D505B99B2755323C00386E9F /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = "<group>"; };
|
||||
D505B99D2756894300386E9F /* ViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModifier.swift; sourceTree = "<group>"; };
|
||||
D50887612A2E35490002B798 /* PyLeap-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PyLeap-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
D50887622A2E35510002B798 /* Wifi_ifaddrs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Wifi_ifaddrs.m; sourceTree = "<group>"; };
|
||||
D517F68026C5771D002996E8 /* FillerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FillerView.swift; sourceTree = "<group>"; };
|
||||
D5199A2E28DD16F100ACC34C /* BleContentTransfer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BleContentTransfer.swift; sourceTree = "<group>"; };
|
||||
D51D1412293A53BD0028AEDD /* WifiCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiCellViewModel.swift; sourceTree = "<group>"; };
|
||||
D520D68F29D4C9380022048D /* WifiServiceCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiServiceCellView.swift; sourceTree = "<group>"; };
|
||||
D520D69129D4C9900022048D /* WifiServiceCellSubView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiServiceCellSubView.swift; sourceTree = "<group>"; };
|
||||
D5267410292E902700D4C79E /* Networking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Networking.swift; sourceTree = "<group>"; };
|
||||
D5269BFF291960A300C0CE4B /* WifiSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WifiSelection.swift; path = "PyLeap/Views/Unpaired View/WifiSelection.swift"; sourceTree = SOURCE_ROOT; };
|
||||
D5269C01291997DE00C0CE4B /* WifiServiceCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WifiServiceCellView.swift; path = ../../../../../../Desktop/WifiServiceCellView.swift; sourceTree = "<group>"; };
|
||||
D5269C032919985400C0CE4B /* WifiServiceCellSubView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WifiServiceCellSubView.swift; path = ../../../../../../Desktop/WifiServiceCellSubView.swift; sourceTree = "<group>"; };
|
||||
D5269C07291AB75800C0CE4B /* WifiPairingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiPairingView.swift; sourceTree = "<group>"; };
|
||||
D52A926C29071DF400973B6B /* SelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionView.swift; sourceTree = "<group>"; };
|
||||
D52A926E29078E0A00973B6B /* WifiServiceSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiServiceSelectionView.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -179,6 +177,7 @@
|
|||
D58D887A26CC02B60085604A /* OnboardingViewPure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewPure.swift; sourceTree = "<group>"; };
|
||||
D58E1C8728A2B10B00AB683E /* WifiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiView.swift; sourceTree = "<group>"; };
|
||||
D58E1C8928A2B15E00AB683E /* WifiViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiViewModel.swift; sourceTree = "<group>"; };
|
||||
D58E1C8C28A2B32C00AB683E /* Wifi_ifaddrs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Wifi_ifaddrs.m; sourceTree = "<group>"; };
|
||||
D58E1C8E28A30A5300AB683E /* WifiNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiNetworkService.swift; sourceTree = "<group>"; };
|
||||
D595FC2D2812C23D00569D8C /* Image Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image Extension.swift"; sourceTree = "<group>"; };
|
||||
D59DFD8E268A4A4D001737F6 /* BTConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTConnectionView.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -195,8 +194,6 @@
|
|||
D5BA1F7E28B66F280012FC62 /* WifiServiceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiServiceManager.swift; sourceTree = "<group>"; };
|
||||
D5BA1F8028B66F920012FC62 /* CircuitPythonService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircuitPythonService.swift; sourceTree = "<group>"; };
|
||||
D5BA1F8228B68ED40012FC62 /* NetworkPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkPeripheral.swift; sourceTree = "<group>"; };
|
||||
D5BBD12B2A1538C100961B68 /* BoardDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardDataProvider.swift; sourceTree = "<group>"; };
|
||||
D5BBD12D2A1C6AB300961B68 /* BleBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BleBannerView.swift; sourceTree = "<group>"; };
|
||||
D5C474AB27E174A5002DD160 /* WebView Content.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WebView Content.swift"; sourceTree = "<group>"; };
|
||||
D5C474C227E39FAD002DD160 /* ReadexPro-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ReadexPro-Bold.ttf"; sourceTree = "<group>"; };
|
||||
D5C474C527E39FC8002DD160 /* ReadexPro-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ReadexPro-Light.ttf"; sourceTree = "<group>"; };
|
||||
|
|
@ -221,6 +218,7 @@
|
|||
D5DD39A628D11817000FAEB8 /* WifiFileTransfer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiFileTransfer.swift; sourceTree = "<group>"; };
|
||||
D5DD39A828D11962000FAEB8 /* WifiTransferService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiTransferService.swift; sourceTree = "<group>"; };
|
||||
D5DD39AA28D234C3000FAEB8 /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
|
||||
D5ECF4B828C8E3C600FBF93D /* PyLeap-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PyLeap-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
D5F53CEA2694B524007634C2 /* Blinka Animation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Blinka Animation.swift"; sourceTree = "<group>"; };
|
||||
D5F53CEC2694B7A9007634C2 /* OnboardingBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingBackgroundView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
|
@ -280,11 +278,9 @@
|
|||
D59DFDB5268CD052001737F6 /* AppEnvironment.swift */,
|
||||
D534F3FB280B59090053699C /* ExampleView.swift */,
|
||||
D544A2502822D4730038D483 /* Spotlight Extension.swift */,
|
||||
D5BBD12A2A15389400961B68 /* Helpers */,
|
||||
D567E2B428B80DC10009F768 /* Outline.md */,
|
||||
D567E2DD28C8D3E20009F768 /* SettingsView */,
|
||||
D5C74DF027EB92E900730505 /* Model */,
|
||||
D59DFDB2268CCEAC001737F6 /* Features */,
|
||||
D59DFDB2268CCEAC001737F6 /* Views */,
|
||||
D5C74DEE27EB91D600730505 /* Networking */,
|
||||
D5C74DED27EB919200730505 /* Resource */,
|
||||
D5C41D6726C5F509004C38E3 /* Download View */,
|
||||
|
|
@ -380,29 +376,23 @@
|
|||
path = BLESetttings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D56FFE1C2A2A4ED500EF1E3B /* Views */ = {
|
||||
D58E1C8628A2B0DE00AB683E /* Wifi View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D567E2DD28C8D3E20009F768 /* SettingsView */,
|
||||
D58E1C8728A2B10B00AB683E /* WifiView.swift */,
|
||||
D567E2B728C137880009F768 /* WifiCell.swift */,
|
||||
D567E2B928C1382E0009F768 /* WifiSubViewCell.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D58E1C8628A2B0DE00AB683E /* Wifi Module */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D56FFE1C2A2A4ED500EF1E3B /* Views */,
|
||||
D51D1412293A53BD0028AEDD /* WifiCellViewModel.swift */,
|
||||
D567E2B928C1382E0009F768 /* WifiSubViewCell.swift */,
|
||||
D58E1C8928A2B15E00AB683E /* WifiViewModel.swift */,
|
||||
D5269C07291AB75800C0CE4B /* WifiPairingView.swift */,
|
||||
D52A926E29078E0A00973B6B /* WifiServiceSelectionView.swift */,
|
||||
D520D68F29D4C9380022048D /* WifiServiceCellView.swift */,
|
||||
D5269BFF291960A300C0CE4B /* WifiSelection.swift */,
|
||||
D5269C01291997DE00C0CE4B /* WifiServiceCellView.swift */,
|
||||
D5269C032919985400C0CE4B /* WifiServiceCellSubView.swift */,
|
||||
D5BA1F7E28B66F280012FC62 /* WifiServiceManager.swift */,
|
||||
D5DD39A628D11817000FAEB8 /* WifiFileTransfer.swift */,
|
||||
D5DD39A828D11962000FAEB8 /* WifiTransferService.swift */,
|
||||
D520D69129D4C9900022048D /* WifiServiceCellSubView.swift */,
|
||||
D5AA27F728CA785B001CCE25 /* CircuitPythonType.swift */,
|
||||
D5482F4A28E75053000B0C8E /* LocalNetworkAuth.swift */,
|
||||
D5AA27F928CA8D46001CCE25 /* WifiStatusHeaderBarView.swift */,
|
||||
|
|
@ -412,17 +402,17 @@
|
|||
D5BA1F8028B66F920012FC62 /* CircuitPythonService.swift */,
|
||||
D58E1C8E28A30A5300AB683E /* WifiNetworkService.swift */,
|
||||
D5BA1F8228B68ED40012FC62 /* NetworkPeripheral.swift */,
|
||||
D50887622A2E35510002B798 /* Wifi_ifaddrs.m */,
|
||||
D50887612A2E35490002B798 /* PyLeap-Bridging-Header.h */,
|
||||
D5D7DF2A28B3E321008552D1 /* BasicCredentials.swift */,
|
||||
D58E1C8C28A2B32C00AB683E /* Wifi_ifaddrs.m */,
|
||||
D5ECF4B828C8E3C600FBF93D /* PyLeap-Bridging-Header.h */,
|
||||
);
|
||||
path = "Wifi Module";
|
||||
path = "Wifi View";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D59DFDB2268CCEAC001737F6 /* Features */ = {
|
||||
D59DFDB2268CCEAC001737F6 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D58E1C8628A2B0DE00AB683E /* Wifi Module */,
|
||||
D58E1C8628A2B0DE00AB683E /* Wifi View */,
|
||||
D5507ACE26C668BC00512BAA /* UI Components */,
|
||||
D59DFDB3268CCEB9001737F6 /* Onboarding Views */,
|
||||
D5C474AA27E1746F002DD160 /* WebView */,
|
||||
|
|
@ -434,7 +424,7 @@
|
|||
D517F68026C5771D002996E8 /* FillerView.swift */,
|
||||
D5D1F4AC27ECFD200040E2BF /* Startup View */,
|
||||
);
|
||||
path = Features;
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D59DFDB3268CCEB9001737F6 /* Onboarding Views */ = {
|
||||
|
|
@ -448,14 +438,6 @@
|
|||
path = "Onboarding Views";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D5BBD12A2A15389400961B68 /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D5BBD12B2A1538C100961B68 /* BoardDataProvider.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D5C41D6726C5F509004C38E3 /* Download View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -553,7 +535,6 @@
|
|||
children = (
|
||||
D59E31A9281B8DD300D24211 /* DownloadState.swift */,
|
||||
D5507ACB26C668BC00512BAA /* BleModuleView.swift */,
|
||||
D5BBD12D2A1C6AB300961B68 /* BleBannerView.swift */,
|
||||
D5507ACC26C668BC00512BAA /* BleModuleViewModel.swift */,
|
||||
D5199A2E28DD16F100ACC34C /* BleContentTransfer.swift */,
|
||||
D5D5BB3828DD19F000E5D93F /* BleContentCommands.swift */,
|
||||
|
|
@ -624,9 +605,8 @@
|
|||
D52F7E682672F4C400911D43 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = YES;
|
||||
LastSwiftUpdateCheck = 1250;
|
||||
LastUpgradeCheck = 1500;
|
||||
LastUpgradeCheck = 1250;
|
||||
TargetAttributes = {
|
||||
D52F7E6F2672F4C400911D43 = {
|
||||
CreatedOnToolsVersion = 12.5;
|
||||
|
|
@ -679,7 +659,6 @@
|
|||
D5D1F4B827ED2F4F0040E2BF /* FileManagerCheck.swift in Sources */,
|
||||
D52BE82A26A0660200630900 /* KeyboardUtils.swift in Sources */,
|
||||
D58182FB27F732E40091C43B /* SubCellViewModel.swift in Sources */,
|
||||
D520D69229D4C9900022048D /* WifiServiceCellSubView.swift in Sources */,
|
||||
D5D5BB3928DD19F000E5D93F /* BleContentCommands.swift in Sources */,
|
||||
D544A1D2281B9BB70038D483 /* Buttons.swift in Sources */,
|
||||
D5D1F4AE27ECFDA10040E2BF /* GifImage.swift in Sources */,
|
||||
|
|
@ -699,9 +678,9 @@
|
|||
D56F640C270242CA000E5975 /* UIColor+LightAndDark.swift in Sources */,
|
||||
D5F53CED2694B7A9007634C2 /* OnboardingBackgroundView.swift in Sources */,
|
||||
D5D1F4B227ECFF760040E2BF /* ProjectsModel.swift in Sources */,
|
||||
D5269C02291997DE00C0CE4B /* WifiServiceCellView.swift in Sources */,
|
||||
D5BA1F7A28B52A490012FC62 /* WifiListDetailView.swift in Sources */,
|
||||
D52F7E742672F4C400911D43 /* PyLeapApp.swift in Sources */,
|
||||
D5BBD12E2A1C6AB300961B68 /* BleBannerView.swift in Sources */,
|
||||
D567E2B628B81B730009F768 /* Queue.swift in Sources */,
|
||||
D534F3FC280B59090053699C /* ExampleView.swift in Sources */,
|
||||
D57858ED28327E18008E8BE4 /* PairingTutorialView.swift in Sources */,
|
||||
|
|
@ -723,6 +702,7 @@
|
|||
D5DD39A728D11817000FAEB8 /* WifiFileTransfer.swift in Sources */,
|
||||
D5AA27FA28CA8D46001CCE25 /* WifiStatusHeaderBarView.swift in Sources */,
|
||||
D5F53CEB2694B524007634C2 /* Blinka Animation.swift in Sources */,
|
||||
D5269C00291960A300C0CE4B /* WifiSelection.swift in Sources */,
|
||||
D5597BF826A9E14B00DF17C0 /* AppDelegate.swift in Sources */,
|
||||
D56F640E270242CA000E5975 /* String+DeletingPrefix.swift in Sources */,
|
||||
D57858F328333CBC008E8BE4 /* TroubleshootView.swift in Sources */,
|
||||
|
|
@ -759,19 +739,18 @@
|
|||
D567E2B828C137880009F768 /* WifiCell.swift in Sources */,
|
||||
D5D1F4B027ECFDE00040E2BF /* NavBarModifier.swift in Sources */,
|
||||
D5597C0C26AF018800DF17C0 /* View+If.swift in Sources */,
|
||||
D58E1C8D28A2B32C00AB683E /* Wifi_ifaddrs.m in Sources */,
|
||||
D56B75D4294BAAB400D008E7 /* BLESettingsView.swift in Sources */,
|
||||
D50887632A2E35510002B798 /* Wifi_ifaddrs.m in Sources */,
|
||||
D52BE7EE269DF36E00630900 /* DownloadViewModel.swift in Sources */,
|
||||
D59E31AA281B8DD300D24211 /* DownloadState.swift in Sources */,
|
||||
D520D69029D4C9380022048D /* WifiServiceCellView.swift in Sources */,
|
||||
D5BA1F7F28B66F280012FC62 /* WifiServiceManager.swift in Sources */,
|
||||
D5C74DF327EB92FA00730505 /* View+Extensions.swift in Sources */,
|
||||
D5AA27F828CA785B001CCE25 /* CircuitPythonType.swift in Sources */,
|
||||
D5199A2F28DD16F100ACC34C /* BleContentTransfer.swift in Sources */,
|
||||
D535E21628E1FA910096E548 /* ScrollRefreshableView.swift in Sources */,
|
||||
D5640216271B54BF00AE1519 /* MainSelectionView.swift in Sources */,
|
||||
D5269C042919985400C0CE4B /* WifiServiceCellSubView.swift in Sources */,
|
||||
D505B99C2755323C00386E9F /* NetworkMonitor.swift in Sources */,
|
||||
D5BBD12C2A1538C100961B68 /* BoardDataProvider.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -815,7 +794,6 @@
|
|||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
|
|
@ -830,7 +808,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
|
|
@ -877,7 +855,6 @@
|
|||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
@ -886,7 +863,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
|
@ -904,22 +881,22 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = PyLeap/PyLeap.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
CURRENT_PROJECT_VERSION = 0;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"PyLeap/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 2X94RM7457;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = PyLeap/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.2;
|
||||
MARKETING_VERSION = 2.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.adafruit.PyLeap;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "PyLeap/Views/Wifi View/PyLeap-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
|
@ -934,22 +911,22 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = PyLeap/PyLeap.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
CURRENT_PROJECT_VERSION = 0;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"PyLeap/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 2X94RM7457;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = PyLeap/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.2;
|
||||
MARKETING_VERSION = 2.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.adafruit.PyLeap;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "PyLeap/Views/Wifi View/PyLeap-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1320"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Default device image.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
|
|
@ -1,47 +0,0 @@
|
|||
//
|
||||
// BleBannerView.swift
|
||||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 5/22/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct BleBannerView: View {
|
||||
var deviceName: String
|
||||
var disconnectAction: () -> Void
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
Image("bluetoothLogo")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 16, height: 16)
|
||||
|
||||
Text(deviceName)
|
||||
.font(Font.custom("ReadexPro-Regular", size: 14))
|
||||
|
||||
Button(action: disconnectAction) {
|
||||
Text("Disconnect")
|
||||
.font(Font.custom("ReadexPro-Bold", size: 14))
|
||||
.underline()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// .background(GeometryReader {
|
||||
// Color.clear.preference(key: ViewHeightKey.self,
|
||||
// value: $0.frame(in: .local).size.height)
|
||||
// })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BleBannerView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
BleBannerView(deviceName: "Test", disconnectAction: {
|
||||
print("Dismiss Action")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
//
|
||||
// MainSelectionView.swift
|
||||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 10/16/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import FileTransferClient
|
||||
|
||||
enum AdafruitDevices {
|
||||
case clue_nrf52840_express
|
||||
case circuitplayground_bluefruit
|
||||
case esp32s2
|
||||
}
|
||||
|
||||
struct MainSelectionView: View {
|
||||
|
||||
@State private var showWebViewPopover: Bool = false
|
||||
|
||||
@State private var inConnectedInSelectionView = false
|
||||
@State private var boardBootInfo = ""
|
||||
@EnvironmentObject var expandedState : ExpandedBLECellState
|
||||
|
||||
@ObservedObject var vm = MainSelectionViewModel()
|
||||
|
||||
|
||||
@State private var isConnected = false
|
||||
|
||||
@State private var test = ""
|
||||
|
||||
@State private var nilBinder = DownloadState.idle
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
|
||||
@AppStorage("shouldShowOnboarding") var shouldShowOnboarding: Bool = true
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack(alignment: .center, spacing: 0) {
|
||||
MainHeaderView()
|
||||
|
||||
HStack(alignment: .center, spacing: 8, content: {
|
||||
Text("Not Connected to a Device.")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 16))
|
||||
Button {
|
||||
rootViewModel.goToSelection()
|
||||
} label: {
|
||||
Text("Connect Now")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 16))
|
||||
.underline()
|
||||
}
|
||||
|
||||
})
|
||||
.padding(.all, 0.0)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(maxHeight: 40)
|
||||
.background(Color("pyleap_burg"))
|
||||
.foregroundColor(.white)
|
||||
|
||||
ScrollView {
|
||||
|
||||
MainSubHeaderView(device: "Adafruit device")
|
||||
|
||||
if vm.pdemos.isEmpty {
|
||||
HStack{
|
||||
Spacer()
|
||||
ProgressView()
|
||||
.scaleEffect(2)
|
||||
Spacer()
|
||||
}
|
||||
.padding(0)
|
||||
|
||||
}
|
||||
|
||||
ScrollViewReader { scroll in
|
||||
|
||||
ForEach(vm.pdemos) { demo in
|
||||
|
||||
if demo.bundleLink == expandedState.currentCell {
|
||||
|
||||
DemoViewCell(result: demo, isExpanded: true, isConnected: $inConnectedInSelectionView, deviceInfo: $boardBootInfo, onViewGeometryChanged: {
|
||||
})
|
||||
.onAppear(){
|
||||
print("Cell Appeared")
|
||||
withAnimation {
|
||||
scroll.scrollTo(demo.id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
DemoViewCell(result: demo, isExpanded: false, isConnected: $inConnectedInSelectionView, deviceInfo: $boardBootInfo, onViewGeometryChanged: {
|
||||
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
.refreshable {
|
||||
vm.pdemos = []
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
vm.networkModel.fetch {
|
||||
|
||||
vm.loadProjectsFromStorage()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.onAppear() {
|
||||
|
||||
|
||||
print("Opened MainSelectionView")
|
||||
}
|
||||
|
||||
.fullScreenCover(isPresented: $shouldShowOnboarding, content: {
|
||||
ExampleView(shouldShowOnboarding: $shouldShowOnboarding)
|
||||
})
|
||||
.preferredColorScheme(.light)
|
||||
.background(Color.white)
|
||||
.navigationBarColor(UIColor(named: "pyleap_gray"))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
//
|
||||
// WifiServiceCellSubView.swift
|
||||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 3/29/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
struct WifiServiceCellSubView: View {
|
||||
let resolvedService: ResolvedService
|
||||
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
|
||||
let userDefaults = UserDefaults.standard
|
||||
private let kPrefix = Bundle.main.bundleIdentifier!
|
||||
|
||||
|
||||
func storeResolvedAddress(service: ResolvedService) {
|
||||
print("Storing resolved address")
|
||||
userDefaults.set(service.ipAddress, forKey: kPrefix+".storeResolvedAddress.ipAddress" )
|
||||
userDefaults.set(service.hostName, forKey: kPrefix+".storeResolvedAddress.hostName" )
|
||||
userDefaults.set(service.device, forKey: kPrefix+".storeResolvedAddress.device" )
|
||||
|
||||
print("Stored UserDefaults")
|
||||
|
||||
print(userDefaults.object(forKey: kPrefix+".storeResolvedAddress.ipAddress"))
|
||||
print(userDefaults.object(forKey: kPrefix+".storeResolvedAddress.hostName"))
|
||||
print(userDefaults.object(forKey: kPrefix+".storeResolvedAddress.device"))
|
||||
}
|
||||
|
||||
func showConfirmationPrompt(service: ResolvedService, hostName: String) {
|
||||
comfirmationAlertMessage(title: "Would you like to connect to \(hostName)?", exitTitle: "Cancel", primaryTitle: "Connect") {
|
||||
storeResolvedAddress(service: service)
|
||||
rootViewModel.goToWifiView()
|
||||
} cancel: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
|
||||
|
||||
|
||||
HStack {
|
||||
VStack {
|
||||
|
||||
Text("Device ID: \(resolvedService.hostName)")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 18))
|
||||
.multilineTextAlignment(.leading)
|
||||
.minimumScaleFactor(0.1)
|
||||
|
||||
Text("Device IP: \(resolvedService.ipAddress)")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 18))
|
||||
.multilineTextAlignment(.leading)
|
||||
.minimumScaleFactor(0.1)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 30)
|
||||
.padding(.vertical, 30)
|
||||
|
||||
HStack (
|
||||
alignment: .center,
|
||||
spacing: 0
|
||||
) {
|
||||
Spacer()
|
||||
Button {
|
||||
showConfirmationPrompt(service: resolvedService, hostName: resolvedService.hostName)
|
||||
|
||||
} label: {
|
||||
Text("Connect")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 25))
|
||||
.foregroundColor(Color.white)
|
||||
.frame(width: 270, height: 50, alignment: .center)
|
||||
.background(Color("pyleap_pink"))
|
||||
.clipShape(Capsule())
|
||||
.padding(.bottom, 30)
|
||||
}
|
||||
Spacer()
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//struct WifiServiceCellSubView_Previews: PreviewProvider {
|
||||
// static var previews: some View {
|
||||
// WifiServiceCellSubView(resolvedService: .con)
|
||||
// }
|
||||
//}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
//
|
||||
// WifiServiceCellView.swift
|
||||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 11/7/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct WifiServiceCellView: View {
|
||||
|
||||
let resolvedService: ResolvedService
|
||||
|
||||
@State private var isExpanded: Bool = false {
|
||||
didSet {
|
||||
onViewGeometryChanged()
|
||||
}
|
||||
}
|
||||
|
||||
let onViewGeometryChanged: ()->Void
|
||||
|
||||
var body: some View {
|
||||
content
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
private var content: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
header
|
||||
|
||||
if isExpanded {
|
||||
|
||||
Group {
|
||||
WifiServiceCellSubView(resolvedService: resolvedService)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeAdafruitString(text: String) -> String {
|
||||
if text.contains("Adafruit") {
|
||||
let parsed = text.replacingOccurrences(of: "Adafruit", with: "")
|
||||
return parsed
|
||||
} else {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
private var header: some View {
|
||||
|
||||
|
||||
|
||||
HStack {
|
||||
Text(removeAdafruitString(text:resolvedService.device))
|
||||
.font(Font.custom("ReadexPro-Regular", size: 24))
|
||||
.minimumScaleFactor(0.1)
|
||||
.lineLimit(1)
|
||||
// .padding(.horizontal, 30)
|
||||
.foregroundColor(.white)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(systemName: "chevron.down")
|
||||
.resizable()
|
||||
.frame(width: 30, height: 15, alignment: .center)
|
||||
.foregroundColor(.white)
|
||||
.padding(.trailing, 30)
|
||||
}
|
||||
|
||||
//.padding(.vertical, 5)
|
||||
.padding(.leading)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 50)
|
||||
.background(Color("alt-gray"))
|
||||
.onTapGesture { isExpanded.toggle() }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// BoardDataProvider.swift
|
||||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 5/17/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
final class BoardDataProvider {
|
||||
|
||||
|
||||
func getBoardID(from prompt: String) -> String? {
|
||||
print("getBoardID function: \(prompt)")
|
||||
|
||||
let boardIDPrefix = "Board ID:"
|
||||
let uidSuffix = "UID"
|
||||
|
||||
if let startRange = prompt.range(of: boardIDPrefix) {
|
||||
let start = startRange.upperBound
|
||||
var end = prompt.endIndex
|
||||
if let endRange = prompt.range(of: uidSuffix) {
|
||||
end = endRange.lowerBound
|
||||
}
|
||||
|
||||
let range = start..<end
|
||||
let boardID = prompt[range].trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
let boardIDWithSpaces = boardID.replacingOccurrences(of: "_", with: " ")
|
||||
|
||||
let capitalizedBoardID = boardIDWithSpaces.capitalized
|
||||
print("Outgoing: \(capitalizedBoardID)")
|
||||
return capitalizedBoardID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCircuitPythonMajorVersion(from prompt: String) -> String? {
|
||||
print("From getCircuitPythonMajorVersion function: \(prompt)")
|
||||
let regexPattern = "CircuitPython (\\d+)"
|
||||
if let regex = try? NSRegularExpression(pattern: regexPattern) {
|
||||
let range = NSRange(location: 0, length: prompt.utf16.count)
|
||||
if let match = regex.firstMatch(in: prompt, options: [], range: range) {
|
||||
if let range = Range(match.range(at: 1), in: prompt) {
|
||||
return String(prompt[range])
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import Foundation
|
|||
/// This is a DataStore class that is used for saving and loading data to/from the file system using the FileManager class.
|
||||
*/
|
||||
|
||||
public class DataStore: ObservableObject {
|
||||
public class DataStore {
|
||||
|
||||
let fileManager = FileManager.default
|
||||
|
||||
|
|
@ -27,8 +27,8 @@ public class DataStore: ObservableObject {
|
|||
/// This method writes it to a file named "StandardPyLeapProjects.json" in the documents directory.
|
||||
*/
|
||||
|
||||
func save(content: [PyProject], completion: @escaping () -> Void) {
|
||||
print(#function)
|
||||
func save(content: [ResultItem], completion: @escaping () -> Void) {
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
if let encodedProjectData = try? encoder.encode(content) {
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ public class DataStore: ObservableObject {
|
|||
/// This method reads the "StandardPyLeapProjects.json" file in the documents directory and decodes it as an array of ResultItem objects, and then appends the customProjects array to it and saves it back to the file.
|
||||
*/
|
||||
|
||||
func save(customProjects: [PyProject], completion: @escaping () -> Void) {
|
||||
func save(customProjects: [ResultItem], completion: @escaping () -> Void) {
|
||||
|
||||
var temp = customProjects
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ public class DataStore: ObservableObject {
|
|||
let savedData = try? Data(contentsOf: fileURL)
|
||||
|
||||
if let savedData = savedData,
|
||||
let savedProjects = try? JSONDecoder().decode([PyProject].self, from: savedData) {
|
||||
let savedProjects = try? JSONDecoder().decode([ResultItem].self, from: savedData) {
|
||||
NotificationCenter.default.post(name: .didCollectCustomProject, object: nil, userInfo: nil)
|
||||
temp.append(contentsOf: savedProjects)
|
||||
|
||||
|
|
@ -76,24 +76,24 @@ public class DataStore: ObservableObject {
|
|||
let savedData = try? Data(contentsOf: fileURL)
|
||||
|
||||
if let savedData = savedData,
|
||||
let savedProjects = try? JSONDecoder().decode([PyProject].self, from: savedData) {
|
||||
let savedProjects = try? JSONDecoder().decode([ResultItem].self, from: savedData) {
|
||||
loadCustomProjectList(contents: savedProjects)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/// This method reads the "StandardPyLeapProjects.json" file in the documents directory, decodes it as an array of ResultItem objects, and returns it.
|
||||
/// : This method reads the "StandardPyLeapProjects.json" file in the documents directory, decodes it as an array of ResultItem objects, and returns it.
|
||||
*/
|
||||
|
||||
func loadDefaultList() -> [PyProject] {
|
||||
func loadDefaultList() -> [ResultItem] {
|
||||
|
||||
var result = [PyProject]()
|
||||
var result = [ResultItem]()
|
||||
let fileURL = documentsDirectory.appendingPathComponent("StandardPyLeapProjects.json")
|
||||
|
||||
let savedData = try? Data(contentsOf: fileURL)
|
||||
|
||||
if let savedData = savedData,
|
||||
let savedProjects = try? JSONDecoder().decode([PyProject].self, from: savedData) {
|
||||
let savedProjects = try? JSONDecoder().decode([ResultItem].self, from: savedData) {
|
||||
result = savedProjects
|
||||
}
|
||||
return result
|
||||
|
|
@ -107,14 +107,14 @@ public class DataStore: ObservableObject {
|
|||
/// This method reads the "CustomProjects.json" file in the documents directory, decodes it as an array of ResultItem objects, appends it to the input array, and then calls
|
||||
*/
|
||||
|
||||
func loadCustomProjectList(contents: [PyProject]) {
|
||||
func loadCustomProjectList(contents: [ResultItem]) {
|
||||
var temp = contents
|
||||
|
||||
let fileURL = documentsDirectory.appendingPathComponent("CustomProjects.json")
|
||||
let savedData = try? Data(contentsOf: fileURL)
|
||||
|
||||
if let savedData = savedData,
|
||||
let savedProjects = try? JSONDecoder().decode([PyProject].self, from: savedData) {
|
||||
let savedProjects = try? JSONDecoder().decode([ResultItem].self, from: savedData) {
|
||||
temp.append(contentsOf: savedProjects)
|
||||
removeDuplicates(projectList: temp)
|
||||
|
||||
|
|
@ -129,9 +129,9 @@ public class DataStore: ObservableObject {
|
|||
/// This method uses the reduce(into:_:) method to iterate over the array, and it builds a new array that only contains unique ResultItem objects based on their bundleLink property. It then calls the save(content:completion:) method to save the new array to "StandardPyLeapProjects.json" file.
|
||||
*/
|
||||
|
||||
func removeDuplicates(projectList: [PyProject]) {
|
||||
func removeDuplicates(projectList: [ResultItem]) {
|
||||
|
||||
let combinedLists = projectList.reduce(into: [PyProject]()) { (result, projectList) in
|
||||
let combinedLists = projectList.reduce(into: [ResultItem]()) { (result, projectList) in
|
||||
|
||||
if !result.contains(where: { $0.bundleLink == projectList.bundleLink }) {
|
||||
result.append(projectList)
|
||||
|
|
@ -146,7 +146,7 @@ public class DataStore: ObservableObject {
|
|||
let savedData = try? Data(contentsOf: fileURL)
|
||||
|
||||
if let savedData = savedData,
|
||||
let savedProjects = try? JSONDecoder().decode([PyProject].self, from: savedData) {
|
||||
let savedProjects = try? JSONDecoder().decode([ResultItem].self, from: savedData) {
|
||||
|
||||
for project in savedProjects {
|
||||
print("CustomProjects name: \(project.projectName)")
|
||||
|
|
|
|||
|
|
@ -8,24 +8,11 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
struct RootResults: Codable {
|
||||
let formatVersion: Int
|
||||
let fileVersion: Int
|
||||
let projects: [PyProject]
|
||||
struct RootResults: Decodable {
|
||||
let projects: [ResultItem]
|
||||
}
|
||||
|
||||
struct PyProject: Codable, Identifiable, Equatable {
|
||||
var id: UUID = UUID()
|
||||
let projectName: String
|
||||
let projectImage: String
|
||||
let description: String
|
||||
let bundleLink: String
|
||||
let learnGuideLink: String
|
||||
let compatibility: [String]
|
||||
let bluetoothCompatible: Bool
|
||||
let wifiCompatible: Bool
|
||||
|
||||
struct ResultItem: Codable, Identifiable, Equatable {
|
||||
enum CodingKeys: CodingKey {
|
||||
case projectName
|
||||
case projectImage
|
||||
|
|
@ -33,21 +20,15 @@ struct PyProject: Codable, Identifiable, Equatable {
|
|||
case bundleLink
|
||||
case learnGuideLink
|
||||
case compatibility
|
||||
case bluetoothCompatible
|
||||
case wifiCompatible
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.projectName = try container.decode(String.self, forKey: .projectName)
|
||||
self.projectImage = try container.decode(String.self, forKey: .projectImage)
|
||||
self.description = try container.decode(String.self, forKey: .description)
|
||||
self.bundleLink = try container.decode(String.self, forKey: .bundleLink)
|
||||
self.learnGuideLink = try container.decode(String.self, forKey: .learnGuideLink)
|
||||
self.compatibility = try container.decode([String].self, forKey: .compatibility)
|
||||
self.bluetoothCompatible = try container.decode(Bool.self, forKey: .bluetoothCompatible)
|
||||
self.wifiCompatible = try container.decode(Bool.self, forKey: .wifiCompatible)
|
||||
}
|
||||
|
||||
var id = UUID()
|
||||
let projectName: String
|
||||
let projectImage: String
|
||||
let description: String
|
||||
let bundleLink: String
|
||||
let learnGuideLink: String
|
||||
let compatibility: [String]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import Foundation
|
|||
import SwiftUI
|
||||
|
||||
class NetworkService: ObservableObject {
|
||||
|
||||
let dataStore = DataStore()
|
||||
|
||||
let thirdPartyBackgroundQueue = DispatchQueue(label: "com.PyLeap.thirdPartyBackgroundQueue", qos: .background, attributes: .concurrent)
|
||||
|
|
@ -35,38 +34,37 @@ class NetworkService: ObservableObject {
|
|||
|
||||
func fetch(completion: @escaping() -> Void) {
|
||||
print("Attempting Network Request")
|
||||
let request = URLRequest(url: URL(string: AdafruitInfo.baseURL)!)
|
||||
let request = URLRequest(url: URL(string: AdafruitInfo.baseURL)!, cachePolicy: URLRequest.CachePolicy.returnCacheDataElseLoad, timeoutInterval: 60.0)
|
||||
let task = session.dataTask(with: request) { data, response, error in
|
||||
|
||||
if let error = error {
|
||||
print("error: \(error)")
|
||||
}
|
||||
|
||||
if let data = data {
|
||||
|
||||
print("Updating UIList with new data...")
|
||||
if let projectData = try? JSONDecoder().decode(RootResults.self, from: data) {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
self.dataStore.save(content: projectData.projects, completion: self.dataStore.loadDefaultProjectList)
|
||||
|
||||
completion()
|
||||
}
|
||||
} else {
|
||||
print("No data found")
|
||||
}
|
||||
} else {
|
||||
print("Updating UIList with Cached data...")
|
||||
DispatchQueue.main.async {
|
||||
self.dataStore.loadDefaultProjectList()
|
||||
completion()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let data = data {
|
||||
print("Updating storage with new data.")
|
||||
do {
|
||||
let projectData = try JSONDecoder().decode(RootResults.self, from: data)
|
||||
dump(projectData.projects)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.dataStore.save(content: projectData.projects, completion: self.dataStore.loadDefaultProjectList)
|
||||
completion()
|
||||
}
|
||||
} catch {
|
||||
print("Decoding error: \(error)")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
task.resume()
|
||||
}
|
||||
|
||||
|
||||
|
||||
func fetchThirdPartyProject(urlString: String?) {
|
||||
|
|
|
|||
|
|
@ -31,10 +31,5 @@ extension View {
|
|||
}
|
||||
}
|
||||
|
||||
func formatDeviceName(_ name: String) -> String {
|
||||
let replaced = name.replacingOccurrences(of: "_", with: " ").replacingOccurrences(of: "-", with: " ")
|
||||
let formatted = replaced.capitalized
|
||||
return formatted
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
BIN
PyLeap/Views/.DS_Store
vendored
Normal file
BIN
PyLeap/Views/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -13,8 +13,8 @@ class BleContentCommands: ObservableObject {
|
|||
|
||||
private weak var fileTransferClient: FileTransferClient?
|
||||
@Published var transmissionProgress: TransmissionProgress?
|
||||
|
||||
@Published var isTransmiting = false
|
||||
@Published var bootUpInfo = String()
|
||||
@Published var counter = 0
|
||||
|
||||
enum ProjectViewError: LocalizedError {
|
||||
|
|
@ -63,6 +63,7 @@ class BleContentCommands: ObservableObject {
|
|||
@Published var lastTransmit: TransmissionLog? = TransmissionLog(type: .write(size: 334))
|
||||
|
||||
|
||||
@Published var activeAlert: ActiveAlert?
|
||||
|
||||
// Data
|
||||
private let bleManager = BleManager.shared
|
||||
|
|
@ -101,7 +102,10 @@ class BleContentCommands: ObservableObject {
|
|||
case .success(let data):
|
||||
self.lastTransmit = TransmissionLog(type: .read(data: data))
|
||||
let str = String(decoding: data, as: UTF8.self)
|
||||
print("Read: \(str)")
|
||||
print("Read: \(str)")
|
||||
self.bootUpInfo = str
|
||||
sharedBootinfo = str
|
||||
|
||||
|
||||
case .failure(let error):
|
||||
self.lastTransmit = TransmissionLog(type: .error(message: error.localizedDescription))
|
||||
|
|
@ -8,24 +8,7 @@
|
|||
import SwiftUI
|
||||
import FileTransferClient
|
||||
|
||||
protocol BoardInfoDelegate: AnyObject {
|
||||
func boardInfoDidUpdate(to newBoard: Board?)
|
||||
}
|
||||
|
||||
enum ListCommandError: Error {
|
||||
case belowMinimum
|
||||
case isPrime
|
||||
}
|
||||
|
||||
class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
||||
|
||||
@Published var currentBoard: Board? {
|
||||
didSet {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static let shared = BleContentTransfer()
|
||||
class BleContentTransfer: ObservableObject {
|
||||
|
||||
private weak var fileTransferClient: FileTransferClient?
|
||||
|
||||
|
|
@ -39,6 +22,7 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
|
||||
@Published var downloadState: DownloadState = .idle
|
||||
|
||||
@State var circuitPythonVersion = String()
|
||||
|
||||
@Published var isTransmiting = false
|
||||
|
||||
|
|
@ -47,14 +31,19 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
@Published var transferError = false
|
||||
|
||||
@Published var downloaderror = false
|
||||
|
||||
|
||||
@Published var bootUpInfo = ""
|
||||
|
||||
|
||||
|
||||
@Published var contentCommands = BleContentCommands()
|
||||
// CLEAN UP
|
||||
var projectDirectories: [URL] = []
|
||||
var projectFiles: [URL] = []
|
||||
var returnedArray = [[String]]()
|
||||
var fileTransferArray : [URL] = []
|
||||
|
||||
var filesReadyForTransfer : [URL] = []
|
||||
|
||||
@Published var sendingBundle = false
|
||||
@Published var didCompleteTranfer = false
|
||||
|
|
@ -68,13 +57,11 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
|
||||
@Published var isConnectedToInternet = false
|
||||
@Published var showAlert = false
|
||||
|
||||
|
||||
var downloadPhases: String = ""
|
||||
|
||||
let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
|
||||
func boardInfoDidUpdate(to newBoard: Board?) {
|
||||
self.currentBoard = newBoard
|
||||
// Add any other logic you need to handle the new board here.
|
||||
}
|
||||
|
||||
enum ProjectViewError: LocalizedError {
|
||||
case fileTransferUndefined
|
||||
|
|
@ -90,9 +77,25 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
}
|
||||
|
||||
init() {
|
||||
getCPVersion()
|
||||
registerNotification(enabled: true)
|
||||
}
|
||||
|
||||
func getCPVersion() {
|
||||
if sharedBootinfo.contains("CircuitPython 7") {
|
||||
print("circuitPythonVersion = 7")
|
||||
circuitPythonVersion = "7"
|
||||
print(circuitPythonVersion)
|
||||
}
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 8") {
|
||||
print("circuitPythonVersion = 8")
|
||||
circuitPythonVersion = "8"
|
||||
print(circuitPythonVersion)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private weak var didCompleteZip: NSObjectProtocol?
|
||||
private weak var didEncounterTransferError: NSObjectProtocol?
|
||||
private weak var downloadErrorDidOccur: NSObjectProtocol?
|
||||
|
|
@ -307,7 +310,14 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// filterCPVersion(incomingArray: regularFileUrls)
|
||||
// filterCPFiles(filesArray: regularFileUrls)
|
||||
|
||||
|
||||
// pathManipulation(arrayOfAny: filterCPVersion(incomingArray: projectDirectories), regularArray: filterCPVersion(incomingArray: projectFiles))
|
||||
|
||||
projectDirectories.removeFirst()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
|
@ -326,28 +336,70 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
|
||||
|
||||
func filterCPVersion(incomingArray: [URL]) -> [URL] {
|
||||
|
||||
let filteredList = incomingArray.filter {
|
||||
let lastPathComponent = $0.lastPathComponent
|
||||
return lastPathComponent != "CircuitPython 8.x"
|
||||
&& lastPathComponent != "CircuitPython 7.x"
|
||||
&& lastPathComponent != "CircuitPython_Templates"
|
||||
print("project name \(projectName)")
|
||||
|
||||
|
||||
for i in incomingArray {
|
||||
print("incoming Array \(i.absoluteString)")
|
||||
}
|
||||
|
||||
|
||||
|
||||
let listWithoutCP8Folder = incomingArray.filter {
|
||||
$0.lastPathComponent != ("CircuitPython 8.x")
|
||||
}
|
||||
|
||||
let listWithoutCP7Folder = listWithoutCP8Folder.filter {
|
||||
$0.lastPathComponent != ("CircuitPython 7.x")
|
||||
}
|
||||
|
||||
//CircuitPython_Templates
|
||||
|
||||
let removedCPTemplates = listWithoutCP7Folder.filter {
|
||||
$0.lastPathComponent != ("CircuitPython_Templates")
|
||||
|
||||
let listForCurrentCPVersion = filteredList.filter {
|
||||
$0.absoluteString.contains("CircuitPython%20\(Board.shared.versionNumber).x")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 8") {
|
||||
let listForCurrentCPVersion = removedCPTemplates.filter {
|
||||
!$0.absoluteString.contains("CircuitPython%207.x")
|
||||
}
|
||||
|
||||
for i in listForCurrentCPVersion {
|
||||
print("listForCurrentCPVersion :- \(i.absoluteString)")
|
||||
}
|
||||
|
||||
return listForCurrentCPVersion
|
||||
|
||||
}
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 7") {
|
||||
|
||||
let listForCurrentCPVersion = listWithoutCP7Folder.filter {
|
||||
!$0.absoluteString.contains("CircuitPython%208.x")
|
||||
}
|
||||
|
||||
for i in listForCurrentCPVersion {
|
||||
print("listForCurrentCPVersion :- \(i.absoluteString)")
|
||||
}
|
||||
return listForCurrentCPVersion
|
||||
}
|
||||
|
||||
return listWithoutCP7Folder
|
||||
}
|
||||
|
||||
|
||||
func makeDirectory(directoryArray: [URL], regularFilesArray: [URL]) {
|
||||
print("\(#function) @Line: \(#line)")
|
||||
var recursiveArray = directoryArray
|
||||
|
||||
|
||||
for i in recursiveArray {
|
||||
print("recursiveArray \(i.absoluteString)")
|
||||
}
|
||||
|
||||
if directoryArray.isEmpty {
|
||||
print("Array is empty. makeDirectory is done - Ready for file transfer!")
|
||||
newTransfer(listOf: regularFilesArray)
|
||||
} else {
|
||||
|
||||
|
|
@ -438,7 +490,10 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
|
||||
}
|
||||
|
||||
|
||||
enum ListCommandError: Error {
|
||||
case belowMinimum
|
||||
case isPrime
|
||||
}
|
||||
|
||||
func checkIfFilesExistOnBoard(url: URL) {
|
||||
|
||||
|
|
@ -472,16 +527,29 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
var tempPathComponents = url.pathComponents
|
||||
print("Incoming URL for makeFileString: \(url.absoluteString)")
|
||||
|
||||
indexOfCP = tempPathComponents.firstIndex(of: "CircuitPython \(Board.shared.versionNumber).x")!
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 7") {
|
||||
|
||||
indexOfCP = tempPathComponents.firstIndex(of: "CircuitPython 7.x")!
|
||||
tempPathComponents.removeSubrange(0...indexOfCP)
|
||||
tempPathComponents.removeLast()
|
||||
var joinedArrayPath = tempPathComponents.joined(separator: "/")
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Outgoing makeFileString: \(joinedArrayPath) for CP 7")
|
||||
return joinedArrayPath
|
||||
}
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 8") {
|
||||
indexOfCP = tempPathComponents.firstIndex(of: "CircuitPython 8.x")!
|
||||
tempPathComponents.removeSubrange(0...indexOfCP)
|
||||
tempPathComponents.removeLast()
|
||||
var joinedArrayPath = tempPathComponents.joined(separator: "/")
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Outgoing makeFileString: \(joinedArrayPath) for CP 8")
|
||||
return joinedArrayPath
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -493,81 +561,256 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
|
||||
print("Incoming URL: \(url.absoluteString) ")
|
||||
|
||||
print(tempPathComponents)
|
||||
indexOfCP = tempPathComponents.firstIndex(of: "CircuitPython \(Board.shared.versionNumber).x")!
|
||||
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 7") {
|
||||
print(tempPathComponents)
|
||||
indexOfCP = tempPathComponents.firstIndex(of: "CircuitPython 7.x")!
|
||||
|
||||
|
||||
tempPathComponents.removeSubrange(0...indexOfCP)
|
||||
var joinedArrayPath = tempPathComponents.joined(separator: "/")
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Outgoing Directory String: \(joinedArrayPath) for CP \(Board.shared.versionNumber)")
|
||||
print("Outgoing String: \(joinedArrayPath) for CP 7")
|
||||
return joinedArrayPath
|
||||
}
|
||||
|
||||
if sharedBootinfo.contains("CircuitPython 8") {
|
||||
indexOfCP = tempPathComponents.firstIndex(of: "CircuitPython 8.x")!
|
||||
tempPathComponents.removeSubrange(0...indexOfCP)
|
||||
var joinedArrayPath = tempPathComponents.joined(separator: "/")
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Outgoing String: \(joinedArrayPath) for CP 8")
|
||||
return joinedArrayPath
|
||||
} else {
|
||||
|
||||
guard let projectName = projectName else {
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
indexOfCP = tempPathComponents.firstIndex(of: projectName)!
|
||||
tempPathComponents.removeSubrange(0...indexOfCP)
|
||||
var joinedArrayPath = tempPathComponents.joined(separator: "/")
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Outgoing String: \(joinedArrayPath) for CP 7")
|
||||
return joinedArrayPath
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
func newTransfer(listOf urls: [URL]) {
|
||||
guard !urls.isEmpty else {
|
||||
print("All Files Transferred! 👍")
|
||||
completedTransfer()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2){
|
||||
self.resetTransferParameters()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
print("\(#function) @Line: \(#line)")
|
||||
var copiedFiles = urls
|
||||
print("Files left for transfer: \(urls.count)")
|
||||
|
||||
print("Attempting to transfer... \(urls.first?.lastPathComponent ?? "No file found")")
|
||||
DispatchQueue.main.async { self.counter += 1 }
|
||||
|
||||
guard let url = urls.first,
|
||||
let data = try? Data(contentsOf: url) else {
|
||||
print("File not found")
|
||||
return
|
||||
}
|
||||
|
||||
let path = isDirectFile(name: url.lastPathComponent) ? url.lastPathComponent : makeDirectoryString(url: url)
|
||||
|
||||
contentCommands.writeFileCommand(path: path, data: data) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
print("Success ✅")
|
||||
self.newTransfer(listOf: Array(urls.dropFirst()))
|
||||
case .failure(let error):
|
||||
print("Transfer Failure \(error)")
|
||||
self.handleTransferError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleTransferError(_ error: Error) {
|
||||
DispatchQueue.main.async {
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print(error)
|
||||
self.downloadState = .failed
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.downloadState = .idle
|
||||
}
|
||||
NotificationCenter.default.post(name: .didEncounterTransferError, object: nil, userInfo: nil)
|
||||
self.counter += 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if copiedFiles.isEmpty {
|
||||
print("All Files Transferred! 👍")
|
||||
self.completedTransfer()
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2){
|
||||
self.sendingBundle = false
|
||||
self.completedTransfer()
|
||||
self.numOfFiles = 0
|
||||
self.counter = 0
|
||||
self.contentList.removeAll()
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
guard let data = try? Data(contentsOf: URL(string: copiedFiles.first!.absoluteString)!) else {
|
||||
print("File not found")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if copiedFiles.first?.lastPathComponent == "code.py" || copiedFiles.first?.lastPathComponent == "README.txt" {
|
||||
|
||||
print("Input for writeFileCommand: \(copiedFiles.first?.absoluteString)")
|
||||
|
||||
|
||||
self.contentCommands.writeFileCommand(path: copiedFiles.first!.lastPathComponent, data: data) { result in
|
||||
switch result {
|
||||
|
||||
case .success(_):
|
||||
print("Success ✅")
|
||||
copiedFiles.removeFirst()
|
||||
self.newTransfer(listOf: copiedFiles)
|
||||
|
||||
case .failure(let error):
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print(error)
|
||||
DispatchQueue.main.async {
|
||||
print("Transfer Failure \(error)")
|
||||
self.downloadState = .failed
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.downloadState = .idle
|
||||
}
|
||||
NotificationCenter.default.post(name: .didEncounterTransferError, object: nil, userInfo: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
print("Checking... 🫥")
|
||||
// print("makeDirectoryString transfer \(makeDirectoryString(url: copiedFiles.first!))")
|
||||
|
||||
let directoryPath = makeDirectoryString(url: copiedFiles.first!)
|
||||
|
||||
private func resetTransferParameters() {
|
||||
sendingBundle = false
|
||||
completedTransfer()
|
||||
numOfFiles = 0
|
||||
counter = 0
|
||||
contentList.removeAll()
|
||||
}
|
||||
print("Input writeFileCommand: \(directoryPath)")
|
||||
self.contentCommands.writeFileCommand(path: directoryPath, data: data) { result in
|
||||
switch result {
|
||||
|
||||
private func isDirectFile(name: String) -> Bool {
|
||||
return name == "code.py" || name == "README.txt"
|
||||
case .success(_):
|
||||
print("Success ✅")
|
||||
copiedFiles.removeFirst()
|
||||
self.newTransfer(listOf: copiedFiles)
|
||||
|
||||
case .failure(let error):
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print(error)
|
||||
DispatchQueue.main.async {
|
||||
print("Transfer Failure \(error)")
|
||||
self.downloadState = .failed
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.downloadState = .idle
|
||||
}
|
||||
NotificationCenter.default.post(name: .didEncounterTransferError, object: nil, userInfo: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
func filePathMod(listOf files: [URL]) {
|
||||
var indexOfCP = 0
|
||||
|
||||
for i in files {
|
||||
print("-\(i.absoluteString)-\n")
|
||||
}
|
||||
|
||||
var tempArray = files
|
||||
|
||||
if files.isEmpty {
|
||||
// Continue
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Done!")
|
||||
// print("RETURNED PATHS: \(returnedArray)\n")
|
||||
|
||||
for i in filesReadyForTransfer {
|
||||
print("\(i)")
|
||||
}
|
||||
|
||||
// self.transferFiles(files: fileArray)
|
||||
|
||||
// validateDirectory(directoryArray: returnedArray, fileArray: fileArray)
|
||||
|
||||
} else {
|
||||
|
||||
var tempPath = files[0].pathComponents
|
||||
|
||||
print("temp path \(tempPath)")
|
||||
|
||||
if tempPath.contains("CircuitPython 7.x") {
|
||||
|
||||
print("\(#function) @Line: \(#line)")
|
||||
|
||||
indexOfCP = tempPath.firstIndex(of: "CircuitPython 7.x")!
|
||||
|
||||
tempPath.removeSubrange(0...indexOfCP)
|
||||
|
||||
print("removeSubrange temp path - \(tempPath)")
|
||||
|
||||
|
||||
tempArray.removeFirst()
|
||||
|
||||
var joinedArrayPath = tempPath.joined(separator: "/")
|
||||
|
||||
|
||||
filesReadyForTransfer.append(URL(string: joinedArrayPath)!)
|
||||
|
||||
filePathMod(listOf: tempArray)
|
||||
|
||||
}
|
||||
|
||||
if tempPath.contains("CircuitPython 8.x") {
|
||||
|
||||
print("\(#function) @Line: \(#line)")
|
||||
|
||||
indexOfCP = tempPath.firstIndex(of: "CircuitPython 8.x")!
|
||||
|
||||
tempPath.removeSubrange(0...indexOfCP)
|
||||
|
||||
print("removeSubrange temp path - \(tempPath)")
|
||||
|
||||
|
||||
tempArray.removeFirst()
|
||||
|
||||
var joinedArrayPath = tempPath.joined(separator: "/")
|
||||
|
||||
filesReadyForTransfer.append(URL(string: joinedArrayPath)!)
|
||||
|
||||
filePathMod(listOf: tempArray)
|
||||
|
||||
}
|
||||
|
||||
|
||||
if tempPath.contains(projectName ?? "unknown") {
|
||||
|
||||
print("\(#function) @Line: \(#line)")
|
||||
|
||||
indexOfCP = tempPath.firstIndex(of: projectName!)!
|
||||
|
||||
tempPath.removeSubrange(0...indexOfCP+1)
|
||||
|
||||
print("removeSubrange temp path - \(tempPath)")
|
||||
|
||||
tempArray.removeFirst()
|
||||
|
||||
var joinedArrayPath = tempPath.joined(separator: "/")
|
||||
|
||||
filesReadyForTransfer.append(URL(string: joinedArrayPath)!)
|
||||
|
||||
filePathMod(listOf: tempArray)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func completedTransfer() {
|
||||
|
||||
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.downloadState = .complete
|
||||
self.didCompleteTranfer = true
|
||||
|
|
@ -581,7 +824,186 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func transferFiles(files: [URL]) {
|
||||
print(#function)
|
||||
var copiedFiles = files
|
||||
print("Number of files in filesArray \(files.count)")
|
||||
print(files)
|
||||
|
||||
if files.isEmpty {
|
||||
print("Array of contents empty - Check other directories")
|
||||
self.completedTransfer()
|
||||
|
||||
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2){
|
||||
self.sendingBundle = false
|
||||
self.completedTransfer()
|
||||
self.numOfFiles = 0
|
||||
self.contentList.removeAll()
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
guard let selectedUrl = files.first else {
|
||||
print("No such file exist here")
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = try? Data(contentsOf: URL(fileURLWithPath: selectedUrl.deletingPathExtension().lastPathComponent, relativeTo: selectedUrl).appendingPathExtension(selectedUrl.pathExtension)) else {
|
||||
print("File not found")
|
||||
return
|
||||
}
|
||||
|
||||
if selectedUrl.deletingLastPathComponent().lastPathComponent == "CircuitPython 7.x"{
|
||||
|
||||
print("Selected Path: \(selectedUrl.path)")
|
||||
|
||||
var tempURL = selectedUrl.pathComponents
|
||||
|
||||
tempURL.removeFirst(12)
|
||||
let joined = tempURL.joined(separator: "/")
|
||||
|
||||
|
||||
var newModPath = tempURL
|
||||
newModPath.removeLast()
|
||||
print("Test file path: \(tempURL)")
|
||||
|
||||
print("File transfer modified path xx: \(joined)")
|
||||
|
||||
|
||||
|
||||
self.contentCommands.writeFileCommand(path: joined, data: data) { result in
|
||||
switch result {
|
||||
|
||||
case .success(_):
|
||||
copiedFiles.removeFirst()
|
||||
self.transferFiles(files: copiedFiles)
|
||||
|
||||
case .failure(_):
|
||||
DispatchQueue.main.async {
|
||||
|
||||
print("Transfer Failure")
|
||||
print("\(joined)")
|
||||
self.downloadState = .failed
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.downloadState = .idle
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NotificationCenter.default.post(name: .didEncounterTransferError, object: nil, userInfo: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
else if selectedUrl.deletingLastPathComponent().lastPathComponent == "lib" {
|
||||
|
||||
|
||||
|
||||
var tempURL = selectedUrl.pathComponents
|
||||
tempURL.removeFirst(12)
|
||||
let joined = tempURL.joined(separator: "/")
|
||||
print("File transfer modified path 11:\(joined)")
|
||||
|
||||
|
||||
|
||||
print("Updated Path:\(joined)")
|
||||
|
||||
|
||||
|
||||
contentCommands.writeFileCommand(path: joined, data: data) { result in
|
||||
switch result {
|
||||
case .success(_):
|
||||
copiedFiles.removeFirst()
|
||||
self.transferFiles(files: copiedFiles)
|
||||
|
||||
case .failure(_):
|
||||
print("Transfer Failure - 2")
|
||||
self.downloadState = .failed
|
||||
NotificationCenter.default.post(name: .didEncounterTransferError, object: nil, userInfo: nil)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if selectedUrl.lastPathComponent == "README.txt" {
|
||||
print("Got one")
|
||||
copiedFiles.removeFirst()
|
||||
self.transferFiles(files: copiedFiles)
|
||||
|
||||
|
||||
} else {
|
||||
var tempURL = selectedUrl.pathComponents
|
||||
|
||||
tempURL.removeFirst(12)
|
||||
let joined = tempURL.joined(separator: "/")
|
||||
print("File transfer modified path: \(joined)")
|
||||
|
||||
|
||||
|
||||
print("Updated Path:\(joined)")
|
||||
|
||||
|
||||
contentCommands.writeFileCommand(path: joined, data: data) { result in
|
||||
switch result {
|
||||
case .success(_):
|
||||
copiedFiles.removeFirst()
|
||||
self.transferFiles(files: copiedFiles)
|
||||
case .failure(let error):
|
||||
print("Failed: \(error): \(result)")
|
||||
NotificationCenter.default.post(name: .didEncounterTransferError, object: nil, userInfo: nil)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.sendingBundle = true
|
||||
}
|
||||
}
|
||||
|
||||
func readMyStatus() {
|
||||
///model.readFile(filename: "boot_out.txt")
|
||||
print(#function)
|
||||
|
||||
print("BOOT INFO: \(bootUpInfo)")
|
||||
|
||||
switch bootUpInfo.description {
|
||||
|
||||
case let str where str.contains("CircuitPython 7"):
|
||||
print("CircuitPython 7")
|
||||
circuitPythonVersion = "CircuitPython 7"
|
||||
|
||||
case let str where str.contains("CircuitPython 8"):
|
||||
print("CircuitPython 8")
|
||||
circuitPythonVersion = "CircuitPython 8"
|
||||
default:
|
||||
print("Unknown Device")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// MARK: System
|
||||
|
||||
struct TransmissionProgress {
|
||||
|
|
@ -625,6 +1047,7 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
@Published var lastTransmit: TransmissionLog? = TransmissionLog(type: .write(size: 334))
|
||||
|
||||
|
||||
@Published var activeAlert: ActiveAlert?
|
||||
|
||||
// Data
|
||||
private let bleManager = BleManager.shared
|
||||
|
|
@ -665,7 +1088,8 @@ class BleContentTransfer: ObservableObject, BoardInfoDelegate {
|
|||
let str = String(decoding: data, as: UTF8.self)
|
||||
print("\(#function) @Line: \(#line)")
|
||||
print("Read: \(str)")
|
||||
|
||||
//self.readMyStatus()
|
||||
self.bootUpInfo = str
|
||||
|
||||
|
||||
|
||||
|
|
@ -12,36 +12,28 @@ class ExpandedBLECellState: ObservableObject {
|
|||
@Published var currentCell = ""
|
||||
}
|
||||
|
||||
class Board: Equatable {
|
||||
|
||||
static func == (lhs: Board, rhs: Board) -> Bool {
|
||||
return lhs.name == rhs.name && lhs.versionNumber == rhs.versionNumber
|
||||
}
|
||||
|
||||
static let shared = Board(name: "Unrecognized Board", versionNumber: "8")
|
||||
|
||||
var name: String
|
||||
var versionNumber: String
|
||||
|
||||
private init(name: String, versionNumber: String) {
|
||||
self.name = name
|
||||
self.versionNumber = versionNumber
|
||||
}
|
||||
}
|
||||
|
||||
struct BleModuleView: View {
|
||||
|
||||
@State var boardInfoForView: Board?
|
||||
// Data
|
||||
enum ActiveAlert: Identifiable {
|
||||
case confirmUnpair(blePeripheral: BlePeripheral)
|
||||
|
||||
var id: Int {
|
||||
switch self {
|
||||
case .confirmUnpair: return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
@EnvironmentObject var expandedState : ExpandedBLECellState
|
||||
@ObservedObject var connectionManager = FileTransferConnectionManager.shared
|
||||
|
||||
@State var unknownBoardName: String?
|
||||
|
||||
|
||||
let selectedPeripheral = FileTransferConnectionManager.shared.selectedPeripheral
|
||||
|
||||
@StateObject var vm = BleModuleViewModel()
|
||||
@StateObject var viewModel = BleModuleViewModel()
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
|
||||
|
||||
|
|
@ -52,6 +44,7 @@ struct BleModuleView: View {
|
|||
@State var isExpanded = true
|
||||
|
||||
@State private var scrollViewID = UUID()
|
||||
@State private var activeAlert: ActiveAlert?
|
||||
@State private var boardBootInfo = ""
|
||||
@State private var inConnectedInSelectionView = true
|
||||
|
||||
|
|
@ -125,7 +118,12 @@ struct BleModuleView: View {
|
|||
.lineLimit(2)
|
||||
|
||||
|
||||
} else if boardBootInfo == "clue_nrf52840_express" {
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
|
||||
if boardBootInfo == "clue_nrf52840_express" {
|
||||
Image("clue")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
|
|
@ -140,20 +138,6 @@ struct BleModuleView: View {
|
|||
.lineLimit(2)
|
||||
.padding(.horizontal, 20)
|
||||
|
||||
} else {
|
||||
Image("Placeholder Board Image")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 200, height: 200)
|
||||
.padding(.horizontal, 60)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
Text(unknownBoardName ?? "")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 30))
|
||||
.minimumScaleFactor(0.01)
|
||||
.multilineTextAlignment(.center)
|
||||
.lineLimit(2)
|
||||
.padding(.horizontal, 20)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -186,14 +170,89 @@ struct BleModuleView: View {
|
|||
|
||||
HeaderView()
|
||||
|
||||
|
||||
|
||||
VStack {
|
||||
|
||||
BleBannerView(deviceName: boardInfoForView?.name ?? "Unknown Device", disconnectAction: {
|
||||
showConfirmationPrompt()
|
||||
})
|
||||
|
||||
|
||||
if boardBootInfo == "circuitplayground_bluefruit" {
|
||||
HStack {
|
||||
|
||||
Image("bluetoothLogo")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 16, height: 16)
|
||||
|
||||
|
||||
Text("Circuit Playground Bluefruit.")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 14))
|
||||
.minimumScaleFactor(0.1)
|
||||
|
||||
|
||||
Button {
|
||||
showConfirmationPrompt()
|
||||
} label: {
|
||||
Text("Disconnect")
|
||||
.font(Font.custom("ReadexPro-Bold", size: 14))
|
||||
.underline()
|
||||
.minimumScaleFactor(0.1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if boardBootInfo == "clue_nrf52840_express" {
|
||||
VStack {
|
||||
|
||||
HStack {
|
||||
Image("bluetoothLogo")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 16, height: 16)
|
||||
|
||||
Text("Adafruit CLUE.")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 14))
|
||||
|
||||
Button {
|
||||
showConfirmationPrompt()
|
||||
|
||||
|
||||
} label: {
|
||||
Text("Disconnect")
|
||||
.font(Font.custom("ReadexPro-Bold", size: 14))
|
||||
.underline()
|
||||
//.minimumScaleFactor(0.1)
|
||||
}
|
||||
|
||||
}
|
||||
// Expandable
|
||||
VStack {
|
||||
Text("More Info")
|
||||
}
|
||||
.background(GeometryReader {
|
||||
Color.clear.preference(key: ViewHeightKey.self,
|
||||
value: $0.frame(in: .local).size.height)
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
.onPreferenceChange(ViewHeightKey.self) { subviewHeight = $0 }
|
||||
.frame(height: isExpanded ? subviewHeight : 50, alignment: .top)
|
||||
|
||||
.clipped()
|
||||
.frame(maxWidth: .infinity)
|
||||
.transition(.move(edge: .bottom))
|
||||
|
||||
|
||||
.onTapGesture {
|
||||
withAnimation(.easeIn(duration: 0.5)) {
|
||||
isExpanded.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.padding(.all, 0.0)
|
||||
.frame(maxWidth: .infinity)
|
||||
|
|
@ -211,32 +270,14 @@ struct BleModuleView: View {
|
|||
MainSubHeaderView(device: "Adafruit CLUE")
|
||||
}
|
||||
|
||||
else if boardInfoForView?.name == "Circuitplayground Bluefruit" {
|
||||
if boardBootInfo == "circuitplayground_bluefruit" {
|
||||
MainSubHeaderView(device: "Circuit Playground")
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
MainSubHeaderView(device: unknownBoardName ?? "device")
|
||||
}
|
||||
|
||||
|
||||
let check = vm.pdemos.filter {
|
||||
|
||||
if boardInfoForView?.name == "Circuitplayground Bluefruit" {
|
||||
let cpbProjects = $0.compatibility.contains("circuitplayground_bluefruit")
|
||||
print("Returned \(cpbProjects) for circuitplayground_bluefruit")
|
||||
return cpbProjects
|
||||
}
|
||||
|
||||
else if boardInfoForView?.name == "Clue Nrf52840 Express" {
|
||||
let clueProjects = $0.compatibility.contains("clue_nrf52840_express")
|
||||
return clueProjects
|
||||
}
|
||||
else {
|
||||
return true
|
||||
}
|
||||
|
||||
let check = viewModel.pdemos.filter {
|
||||
$0.compatibility.contains(boardBootInfo)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -270,9 +311,6 @@ struct BleModuleView: View {
|
|||
.id(self.scrollViewID)
|
||||
}
|
||||
.environmentObject(expandedState)
|
||||
.refreshable {
|
||||
vm.fetchAndLoadProjectsFromStorage()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -280,37 +318,50 @@ struct BleModuleView: View {
|
|||
.background(Color.white)
|
||||
|
||||
|
||||
.onChange(of: vm.bootUpInfo, perform: { newValue in
|
||||
vm.readMyStatus()
|
||||
.onChange(of: viewModel.bootUpInfo, perform: { newValue in
|
||||
viewModel.readMyStatus()
|
||||
|
||||
print("newValue \(newValue)")
|
||||
boardBootInfo = newValue
|
||||
})
|
||||
|
||||
.onChange(of: connectionManager.selectedClient) { selectedClient in
|
||||
vm.setup(fileTransferClient: selectedClient)
|
||||
viewModel.setup(fileTransferClient: selectedClient)
|
||||
}
|
||||
|
||||
.onChange(of: vm.connectedBoard, perform: { newValue in
|
||||
dump(newValue)
|
||||
boardInfoForView = newValue
|
||||
unknownBoardName = newValue?.name
|
||||
})
|
||||
|
||||
.onAppear(){
|
||||
print("Opened BleModuleView")
|
||||
// networkServiceModel.fetch()
|
||||
|
||||
|
||||
vm.setup(fileTransferClient:connectionManager.selectedClient)
|
||||
viewModel.setup(fileTransferClient:connectionManager.selectedClient)
|
||||
|
||||
connectionManager.isSelectedPeripheralReconnecting = true
|
||||
|
||||
vm.readFile(filename: "boot_out.txt")
|
||||
|
||||
print("x\(boardBootInfo)")
|
||||
|
||||
viewModel.readFile(filename: "boot_out.txt")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct Alerts: ViewModifier {
|
||||
@Binding var activeAlert: ActiveAlert?
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.alert(item: $activeAlert, content: { alert in
|
||||
switch alert {
|
||||
case .confirmUnpair(let blePeripheral):
|
||||
return Alert(
|
||||
title: Text("Confirm disconnect \(blePeripheral.name ?? "")"),
|
||||
message: nil,
|
||||
primaryButton: .destructive(Text("Disconnect")) {
|
||||
//BleAutoReconnect.clearAutoconnectPeripheral()
|
||||
BleManager.shared.disconnect(from: blePeripheral)
|
||||
},
|
||||
secondaryButton: .cancel(Text("Cancel")) {})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ViewHeightKey: PreferenceKey {
|
||||
|
|
@ -10,57 +10,30 @@ import Zip
|
|||
import FileTransferClient
|
||||
|
||||
class BleModuleViewModel: ObservableObject {
|
||||
|
||||
weak var delegate: BoardInfoDelegate?
|
||||
|
||||
@Published var boardInfoForView: Board? {
|
||||
didSet {
|
||||
print("Changed")
|
||||
delegate?.boardInfoDidUpdate(to: boardInfoForView)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private weak var fileTransferClient: FileTransferClient?
|
||||
@State var contentTransfer = BleContentTransfer()
|
||||
@StateObject var contentTransfer = BleContentTransfer()
|
||||
|
||||
@Published var entries = [BlePeripheral.DirectoryEntry]()
|
||||
@Published var isTransmiting = false
|
||||
@Published var bootUpInfo = ""
|
||||
|
||||
|
||||
var boardDataProvider = BoardDataProvider()
|
||||
var connectedBoard: Board?
|
||||
|
||||
let dataStore = DataStore()
|
||||
@ObservedObject var networkModel = NetworkService()
|
||||
|
||||
let dataStore = DataStore()
|
||||
|
||||
@Published var pdemos : [PyProject] = []
|
||||
|
||||
func loadProjectsFromStorage() {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
|
||||
func fetchAndLoadProjectsFromStorage() {
|
||||
self.networkModel.fetch {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
}
|
||||
|
||||
@Published var pdemos : [ResultItem] = []
|
||||
|
||||
init() {
|
||||
loadProjectsFromStorage()
|
||||
self.delegate = contentTransfer
|
||||
pdemos = dataStore.loadDefaultList()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
enum ProjectViewError: LocalizedError {
|
||||
case fileTransferUndefined
|
||||
}
|
||||
|
||||
|
||||
func readMyStatus() {
|
||||
|
||||
|
||||
print("BOOT INFO: \(bootUpInfo)")
|
||||
|
||||
switch bootUpInfo.description {
|
||||
|
|
@ -68,11 +41,11 @@ class BleModuleViewModel: ObservableObject {
|
|||
case let str where str.contains("circuitplayground_bluefruit"):
|
||||
print("Circuit Playground Bluefruit device")
|
||||
bootUpInfo = "circuitplayground_bluefruit"
|
||||
|
||||
|
||||
case let str where str.contains("clue_nrf52840_express"):
|
||||
print("Clue device")
|
||||
bootUpInfo = "clue_nrf52840_express"
|
||||
|
||||
|
||||
default:
|
||||
print("Unknown Device")
|
||||
}
|
||||
|
|
@ -98,6 +71,7 @@ class BleModuleViewModel: ObservableObject {
|
|||
|
||||
@Published var transmissionProgress: TransmissionProgress?
|
||||
@Published var lastTransmit: TransmissionLog? = TransmissionLog(type: .write(size: 334))
|
||||
@Published var activeAlert: ActiveAlert?
|
||||
// Data
|
||||
private let bleManager = BleManager.shared
|
||||
|
||||
|
|
@ -126,7 +100,7 @@ class BleModuleViewModel: ObservableObject {
|
|||
return modeText
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Setup
|
||||
func onAppear() {
|
||||
//registerNotifications(enabled: true)
|
||||
|
|
@ -147,28 +121,6 @@ class BleModuleViewModel: ObservableObject {
|
|||
|
||||
}
|
||||
|
||||
|
||||
func setupBoardInfoForDisplay(_ boardInfo: String?) -> Board {
|
||||
// First, safely unwrap the optional 'boardInfo' string
|
||||
guard let info = boardInfo else {
|
||||
print("boardInfo is nil")
|
||||
return Board.shared
|
||||
}
|
||||
|
||||
let boardID = boardDataProvider.getBoardID(from: info) ?? "Unrecognized Board"
|
||||
// Board default version is set to 8
|
||||
let boardVersion = boardDataProvider.getCircuitPythonMajorVersion(from: info) ?? "8"
|
||||
|
||||
Board.shared.name = boardID
|
||||
Board.shared.versionNumber = boardVersion
|
||||
|
||||
// Create a new Board object with the acquired name and version
|
||||
let board = Board.shared
|
||||
|
||||
return board
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
func readFile(filename: String) {
|
||||
|
|
@ -183,10 +135,8 @@ class BleModuleViewModel: ObservableObject {
|
|||
let str = String(decoding: data, as: UTF8.self)
|
||||
|
||||
print("Read: \(str)")
|
||||
|
||||
self.connectedBoard = self.setupBoardInfoForDisplay(str)
|
||||
self.boardInfoForView = self.connectedBoard
|
||||
|
||||
self.bootUpInfo = str
|
||||
sharedBootinfo = str
|
||||
|
||||
case .failure(let error):
|
||||
self.lastTransmit = TransmissionLog(type: .error(message: error.localizedDescription))
|
||||
|
|
@ -394,4 +344,18 @@ class BleModuleViewModel: ObservableObject {
|
|||
completion?(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public var sharedBootinfo = ""
|
||||
|
||||
enum ActiveAlert: Identifiable {
|
||||
case error(error: Error)
|
||||
|
||||
var id: Int {
|
||||
switch self {
|
||||
case .error: return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,13 +10,13 @@ import FileTransferClient
|
|||
|
||||
struct DemoSubview: View {
|
||||
|
||||
let result: PyProject
|
||||
@Binding var bindingString: String
|
||||
|
||||
let result: ResultItem
|
||||
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
@StateObject var viewModel = SubCellViewModel()
|
||||
//@StateObject var contentTransfer = BleContentTransfer()
|
||||
@StateObject var contentTransfer = BleContentTransfer.shared
|
||||
|
||||
@StateObject var contentTransfer = BleContentTransfer()
|
||||
|
||||
@ObservedObject var connectionManager = FileTransferConnectionManager.shared
|
||||
|
||||
|
|
@ -150,7 +150,16 @@ Try again later
|
|||
|
||||
if isConnected {
|
||||
|
||||
|
||||
if result.compatibility.contains(bindingString) {
|
||||
|
||||
// Button {
|
||||
// viewModel.deleteStoredFilesInFM()
|
||||
// } label: {
|
||||
// Text("Delete File Manager Contents")
|
||||
// .bold()
|
||||
// .padding(12)
|
||||
// }
|
||||
|
||||
if contentTransfer.downloadState == .idle {
|
||||
|
||||
Button(action: {
|
||||
|
|
@ -201,7 +210,7 @@ Try again later
|
|||
CompleteButton()
|
||||
.padding(.top, 20)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -222,7 +231,9 @@ Try again later
|
|||
|
||||
print("On Appear")
|
||||
contentTransfer.contentCommands.setup(fileTransferClient: connectionManager.selectedClient)
|
||||
}
|
||||
|
||||
// viewModel.readFile(filename: "boot_out.txt")
|
||||
}
|
||||
|
||||
.onChange(of: contentTransfer.transferError, perform: { newValue in
|
||||
if newValue {
|
||||
|
|
@ -235,9 +246,15 @@ Try again later
|
|||
showDownloadErrorMessage()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
// .onChange(of: connectionManager.selectedClient) { selectedClient in
|
||||
// viewModel.setup(fileTransferClient: selectedClient)
|
||||
// }
|
||||
|
||||
.onAppear(perform: {
|
||||
|
||||
contentTransfer.readMyStatus()
|
||||
viewModel.searchPathForProject(nameOf: result.projectName)
|
||||
|
||||
if viewModel.projectDownloaded {
|
||||
|
|
@ -11,7 +11,7 @@ struct DemoViewCell: View {
|
|||
|
||||
@EnvironmentObject var expandedState : ExpandedBLECellState
|
||||
|
||||
let result : PyProject
|
||||
let result : ResultItem
|
||||
|
||||
@State var isExpanded: Bool = false {
|
||||
didSet {
|
||||
|
|
@ -36,7 +36,7 @@ struct DemoViewCell: View {
|
|||
if isExpanded {
|
||||
|
||||
Group {
|
||||
DemoSubview(result: result, isConnected: $isConnected)
|
||||
DemoSubview(bindingString: $deviceInfo, result: result, isConnected: $isConnected)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -54,7 +54,8 @@ struct RootView: View {
|
|||
case .selection:
|
||||
SelectionView()
|
||||
|
||||
|
||||
case .wifiSelection:
|
||||
WifiSelection()
|
||||
|
||||
case .wifiPairingTutorial:
|
||||
WifiPairingView()
|
||||
|
|
@ -47,7 +47,7 @@ public class RootViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
func goToWiFiSelection() {
|
||||
destination = .wifiServiceSelection
|
||||
destination = .wifiSelection
|
||||
}
|
||||
|
||||
func goToWifiView() {
|
||||
|
|
@ -16,6 +16,8 @@ struct WifiHeaderView: View {
|
|||
|
||||
VStack {
|
||||
|
||||
|
||||
|
||||
HStack (alignment: .center, spacing: 0) {
|
||||
|
||||
Image(systemName: "gearshape")
|
||||
246
PyLeap/Views/Unpaired View/MainSelectionView.swift
Normal file
246
PyLeap/Views/Unpaired View/MainSelectionView.swift
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
//
|
||||
// MainSelectionView.swift
|
||||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 10/16/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import FileTransferClient
|
||||
|
||||
enum AdafruitDevices {
|
||||
case clue_nrf52840_express
|
||||
case circuitplayground_bluefruit
|
||||
case esp32s2
|
||||
}
|
||||
|
||||
struct MainSelectionView: View {
|
||||
|
||||
@State private var showWebViewPopover: Bool = false
|
||||
|
||||
@State private var inConnectedInSelectionView = true
|
||||
@State private var boardBootInfo = ""
|
||||
@EnvironmentObject var expandedState : ExpandedBLECellState
|
||||
|
||||
@ObservedObject var viewModel = MainSelectionViewModel()
|
||||
|
||||
|
||||
@State private var isConnected = false
|
||||
|
||||
@State private var test = ""
|
||||
|
||||
@State private var nilBinder = DownloadState.idle
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
|
||||
@AppStorage("shouldShowOnboarding") var shouldShowOnboarding: Bool = true
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack(alignment: .center, spacing: 0) {
|
||||
MainHeaderView()
|
||||
|
||||
HStack(alignment: .center, spacing: 8, content: {
|
||||
Text("Not Connected to a Device.")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 16))
|
||||
Button {
|
||||
rootViewModel.goToSelection()
|
||||
} label: {
|
||||
Text("Connect Now")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 16))
|
||||
.underline()
|
||||
}
|
||||
|
||||
})
|
||||
.padding(.all, 0.0)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(maxHeight: 40)
|
||||
.background(Color("pyleap_burg"))
|
||||
.foregroundColor(.white)
|
||||
|
||||
ScrollView {
|
||||
|
||||
MainSubHeaderView(device: "Adafruit device")
|
||||
|
||||
if viewModel.pdemos.isEmpty {
|
||||
HStack{
|
||||
Spacer()
|
||||
ProgressView()
|
||||
.scaleEffect(2)
|
||||
Spacer()
|
||||
}
|
||||
.padding(0)
|
||||
|
||||
}
|
||||
|
||||
ScrollViewReader { scroll in
|
||||
|
||||
|
||||
|
||||
|
||||
ForEach(viewModel.pdemos) { demo in
|
||||
|
||||
if demo.bundleLink == expandedState.currentCell {
|
||||
|
||||
DemoViewCell(result: demo, isExpanded: true, isConnected: $inConnectedInSelectionView, deviceInfo: $boardBootInfo, onViewGeometryChanged: {
|
||||
})
|
||||
.onAppear(){
|
||||
print("Cell Appeared")
|
||||
withAnimation {
|
||||
scroll.scrollTo(demo.id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
DemoViewCell(result: demo, isExpanded: false, isConnected: $inConnectedInSelectionView, deviceInfo: $boardBootInfo, onViewGeometryChanged: {
|
||||
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.onDisappear() {
|
||||
|
||||
}
|
||||
|
||||
/// **Pull down to Refresh feature**
|
||||
// ScrollRefreshableView(title: "Refresh", tintColor: .purple) {
|
||||
// HStack{
|
||||
// Spacer()
|
||||
// MainSubHeaderView()
|
||||
// Spacer()
|
||||
// }
|
||||
// .padding(0)
|
||||
//
|
||||
// if networkModel.pdemos.isEmpty {
|
||||
// HStack{
|
||||
// Spacer()
|
||||
// ProgressView()
|
||||
// .scaleEffect(2)
|
||||
// Spacer()
|
||||
// }
|
||||
// .padding(0)
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }// } onRefresh: {
|
||||
// self.networkModel.fetch()
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
.onChange(of: viewModel.pdemos, perform: { newValue in
|
||||
print("Update")
|
||||
|
||||
|
||||
})
|
||||
.onAppear() {
|
||||
|
||||
|
||||
print("Opened MainSelectionView")
|
||||
}
|
||||
|
||||
.fullScreenCover(isPresented: $shouldShowOnboarding, content: {
|
||||
ExampleView(shouldShowOnboarding: $shouldShowOnboarding)
|
||||
})
|
||||
.preferredColorScheme(.light)
|
||||
.background(Color.white)
|
||||
.navigationBarColor(UIColor(named: "pyleap_gray"))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//struct MainSelectionView_Previews: PreviewProvider {
|
||||
// static var previews: some View {
|
||||
// MainSelectionView()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//struct MainSelectionView: View {
|
||||
//
|
||||
// @State private var showWebViewPopover: Bool = false
|
||||
// @ObservedObject var networkModel = NetworkService()
|
||||
// @ObservedObject var viewModel = MainSelectionViewModel()
|
||||
// @State private var test = ""
|
||||
// @State private var nilBinder = DownloadState.idle
|
||||
// @EnvironmentObject var rootViewModel: RootViewModel
|
||||
// @AppStorage("shouldShowOnboarding") var shouldShowOnboarding: Bool = true
|
||||
//
|
||||
// var body: some View {
|
||||
// VStack(alignment: .center, spacing: 0) {
|
||||
// MainHeaderView()
|
||||
// connectionMessageView()
|
||||
// ScrollView {
|
||||
// MainSubHeaderView(device: "Adafruit device")
|
||||
// if networkModel.pdemos.isEmpty {
|
||||
// loadingIndicatorView()
|
||||
// }
|
||||
// ScrollViewReader { scroll in
|
||||
// ForEach(networkModel.pdemos) { demo in
|
||||
// demoViewCell(demo: demo, scroll: scroll)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private func connectionMessageView() -> some View {
|
||||
// HStack(alignment: .center, spacing: 8) {
|
||||
// Text("Not Connected to a Device.")
|
||||
// .font(Font.custom("ReadexPro-Regular", size: 16))
|
||||
// Button {
|
||||
// rootViewModel.goToSelection()
|
||||
// } label: {
|
||||
// Text("Connect Now")
|
||||
// .font(Font.custom("ReadexPro-Regular", size: 16))
|
||||
// .underline()
|
||||
// }
|
||||
// }
|
||||
// .padding(.all, 0.0)
|
||||
// .frame(maxWidth: .infinity)
|
||||
// .frame(maxHeight: 40)
|
||||
// .background(Color("pyleap_burg"))
|
||||
// .foregroundColor(.white)
|
||||
// }
|
||||
//
|
||||
// private func loadingIndicatorView() -> some View {
|
||||
// HStack{
|
||||
// Spacer()
|
||||
// ProgressView()
|
||||
// .scaleEffect(2)
|
||||
// Spacer()
|
||||
// }
|
||||
// .padding(0)
|
||||
// }
|
||||
//
|
||||
// private func demoViewCell(demo: Demo, scroll: ScrollViewProxy) -> some View {
|
||||
// if demo.bundleLink == expandedState.currentCell {
|
||||
// DemoViewCell(result: demo, isExpanded: true, isConnected: $inConnectedInSelectionView, deviceInfo: $boardBootInfo, onViewGeometryChanged: {
|
||||
// })
|
||||
// .onAppear(){
|
||||
// print("Cell Appeared")
|
||||
// withAnimation {
|
||||
// scroll.scrollTo(demo.id)
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// DemoViewCell(result: demo, isExpanded: false, isConnected: $inConnectedInSelectionView, deviceInfo: $boardBootInfo, onViewGeometryChanged: {
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
|
@ -17,23 +17,23 @@ class InternetConnectionManager: ObservableObject {
|
|||
@Published var isConnected = false
|
||||
|
||||
init() {
|
||||
|
||||
|
||||
startMonitoring(completion: {
|
||||
monitor.pathUpdateHandler = { path in
|
||||
|
||||
DispatchQueue.main.async {
|
||||
let newIsConnected = path.status == .satisfied
|
||||
if self.isConnected != newIsConnected {
|
||||
self.isConnected = newIsConnected
|
||||
print("net: \(path.status) \(self.isConnected)")
|
||||
}
|
||||
if self.isConnected != newIsConnected {
|
||||
self.isConnected = newIsConnected
|
||||
print("net: \(path.status) \(self.isConnected)")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func startMonitoring(completion:()->Void) {
|
||||
print("Start Monitoring Network")
|
||||
print("Start Monitoring Network")
|
||||
monitor.start(queue: queue)
|
||||
completion()
|
||||
|
||||
|
|
@ -57,43 +57,32 @@ class MainSelectionViewModel: ObservableObject {
|
|||
|
||||
let dataStore = DataStore()
|
||||
|
||||
@Published var pdemos: [PyProject] = []
|
||||
|
||||
@Published var pdemos : [ResultItem] = []
|
||||
var networkMonitorCancellable: AnyCancellable?
|
||||
|
||||
init() {
|
||||
startUp()
|
||||
}
|
||||
|
||||
|
||||
func loadProjectsFromStorage() {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
|
||||
func fetchAndLoadProjectsFromStorage() {
|
||||
self.networkModel.fetch {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
}
|
||||
|
||||
func startUp(){
|
||||
let fileURL = documentsDirectory.appendingPathComponent("StandardPyLeapProjects.json")
|
||||
|
||||
|
||||
networkMonitorCancellable = networkMonitor.$isConnected.sink { isConnected in
|
||||
|
||||
if isConnected {
|
||||
// Perform some action when the device is connected to the internet.
|
||||
self.fetchAndLoadProjectsFromStorage()
|
||||
print("The device is currently connected to the internet.")
|
||||
|
||||
} else {
|
||||
print("The device is not currently connected to the internet.")
|
||||
// Perform some action when the device is not connected to the internet.
|
||||
print("Loading cached remote data.")
|
||||
self.loadProjectsFromStorage()
|
||||
|
||||
}
|
||||
}
|
||||
if isConnected {
|
||||
print("The device is currently connected to the internet.")
|
||||
// Perform some action when the device is connected to the internet.
|
||||
self.networkModel.fetch {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
|
||||
} else {
|
||||
print("The device is not currently connected to the internet.")
|
||||
// Perform some action when the device is not connected to the internet.
|
||||
print("Loading cached remote data.")
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ struct SelectionView: View {
|
|||
Button {
|
||||
rootViewModel.goToWiFiSelection()
|
||||
} label: {
|
||||
Text("WiFi")
|
||||
Text("Wifi")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 25))
|
||||
.foregroundColor(Color.white)
|
||||
.frame(width: 270, height: 50, alignment: .center)
|
||||
|
|
@ -110,9 +110,6 @@ struct SelectionView: View {
|
|||
|
||||
}
|
||||
.padding(.bottom, 60)
|
||||
.onAppear() {
|
||||
print("In Selection view")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -175,9 +175,6 @@ Find more information on adding your own project here:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extension View {
|
||||
|
||||
func comfirmationAlertMessage(title: String, exitTitle: String, primaryTitle: String,disconnect: @escaping() -> (),cancel: @escaping() -> ()){
|
||||
|
|
@ -19,7 +19,7 @@ struct WifiCell: View {
|
|||
|
||||
@EnvironmentObject var expandedState : ExpandedState
|
||||
|
||||
let result : PyProject
|
||||
let result : ResultItem
|
||||
|
||||
@State var isExpanded: Bool = false {
|
||||
didSet {
|
||||
|
|
@ -17,7 +17,52 @@ struct TestIndex {
|
|||
}
|
||||
|
||||
class WifiFileTransfer: ObservableObject {
|
||||
|
||||
|
||||
// func fetchDocuments<T: Sequence>(in sequence: T) where T.Element == Int {
|
||||
// var documentNumbers = sequence.map { String($0) }
|
||||
//
|
||||
// let timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { [weak self] timer in
|
||||
// guard
|
||||
// let self = self,
|
||||
// let documentNumber = documentNumbers.first
|
||||
// else {
|
||||
// timer.invalidate()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// self.fetchDocument(byNumber: documentNumber)
|
||||
// documentNumbers.removeLast()
|
||||
// }
|
||||
// timer.fire() // if you don't want to wait 2 seconds for the first one to fire, go ahead and fire it manually
|
||||
// }
|
||||
|
||||
|
||||
func fetchDocumentsq<T: Sequence>(in sequence: T) where T.Element == URL {
|
||||
|
||||
print(sequence)
|
||||
|
||||
guard let value = sequence.first(where: { _ in true }) else {
|
||||
print("Complete - fetchDocumentsq")
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// let docNumber = String(value)
|
||||
// fetchDocument(byNumber: docNumber)
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
|
||||
// self?.fetchDocuments(in: sequence.dropFirst())
|
||||
|
||||
print(value)
|
||||
self?.fetchDocumentsq(in: sequence.dropFirst())
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct TestIndex {
|
||||
var count = 0
|
||||
var numberOfFiles = 0
|
||||
|
|
@ -29,10 +74,13 @@ class WifiFileTransfer: ObservableObject {
|
|||
downloadState = .idle
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
var testIndex = TestIndex()
|
||||
|
||||
|
||||
func copy(with zone: NSZone? = nil) -> Any {
|
||||
let copy = WifiFileTransfer()
|
||||
copy.counter = counter
|
||||
|
|
@ -77,7 +125,6 @@ class WifiFileTransfer: ObservableObject {
|
|||
|
||||
func printArray(array: [Any]) {
|
||||
|
||||
print("From print array:")
|
||||
for i in array {
|
||||
print("\(i)")
|
||||
}
|
||||
|
|
@ -292,20 +339,34 @@ class WifiFileTransfer: ObservableObject {
|
|||
|
||||
func filterOutCPDirectories(urls: [URL]) -> [URL] {
|
||||
// Removes - CircuitPython 8.x directory at the lastPathComponent
|
||||
let filteredList = urls.filter {
|
||||
let lastPathComponent = $0.lastPathComponent
|
||||
return lastPathComponent != "CircuitPython 8.x"
|
||||
&& lastPathComponent != "CircuitPython 7.x"
|
||||
&& lastPathComponent != "CircuitPython_Templates"
|
||||
let removingCP8FromArray = urls.filter {
|
||||
$0.lastPathComponent != ("CircuitPython 8.x")
|
||||
}
|
||||
|
||||
let listForCurrentCPVersion = filteredList.filter {
|
||||
$0.absoluteString.contains("CircuitPython%20\(Board.shared.versionNumber).x")
|
||||
// Removes - CircuitPython 7.x directory at the lastPathComponent
|
||||
let removingCP7FromArray = removingCP8FromArray.filter {
|
||||
$0.lastPathComponent != ("CircuitPython 7.x")
|
||||
}
|
||||
|
||||
printArray(array: listForCurrentCPVersion)
|
||||
if WifiCPVersion.versionNumber == 8 {
|
||||
let listForCurrentCPVersion = removingCP7FromArray.filter {
|
||||
!$0.absoluteString.contains("CircuitPython%207.x")
|
||||
|
||||
}
|
||||
return listForCurrentCPVersion
|
||||
}
|
||||
|
||||
return listForCurrentCPVersion
|
||||
if WifiCPVersion.versionNumber == 7 {
|
||||
let listForCurrentCPVersion = removingCP7FromArray.filter {
|
||||
!$0.absoluteString.contains("CircuitPython%208.x")
|
||||
|
||||
}
|
||||
return listForCurrentCPVersion
|
||||
}
|
||||
|
||||
|
||||
|
||||
return removingCP7FromArray
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -358,6 +419,8 @@ class WifiFileTransfer: ObservableObject {
|
|||
DispatchQueue.main.async {
|
||||
self.numOfFiles = tempArray.count
|
||||
self.makeFile(files: tempArray)
|
||||
// self.testIndex.numberOfFiles = self.numOfFiles
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -555,6 +618,7 @@ class WifiFileTransfer: ObservableObject {
|
|||
printArray(array: files)
|
||||
var copiedArray = files
|
||||
|
||||
// self.fetchDocumentsq(in: files)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.counter += 1
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// PyLeap
|
||||
//
|
||||
// Created by Trevor Beaton on 10/24/22.
|
||||
// Testing
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
|
|
@ -9,16 +9,19 @@ import SwiftUI
|
|||
import Foundation
|
||||
|
||||
struct WifiStatusConnectedView: View {
|
||||
|
||||
let userDefaults = UserDefaults.standard
|
||||
private let kPrefix = Bundle.main.bundleIdentifier!
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
|
||||
@Binding var hostName: String
|
||||
|
||||
var disconnectAction: () -> Void
|
||||
|
||||
func removeAdafruitString(from boardName: String) -> String {
|
||||
let removeString = "Adafruit"
|
||||
let updatedText = boardName.replacingOccurrences(of: removeString, with: "")
|
||||
|
||||
return updatedText
|
||||
func showConfirmationPrompt() {
|
||||
comfirmationAlertMessage(title: "Are you sure you want to disconnect?", exitTitle: "Cancel", primaryTitle: "Disconnect") {
|
||||
rootViewModel.goToSelection()
|
||||
} cancel: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -30,13 +33,16 @@ struct WifiStatusConnectedView: View {
|
|||
.frame(width: 20, height: 20)
|
||||
.padding(5)
|
||||
|
||||
Text("Connected to \(hostName) ")
|
||||
Text("Connected to \(hostName). ")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 14))
|
||||
|
||||
Button(action: disconnectAction) {
|
||||
Button {
|
||||
showConfirmationPrompt()
|
||||
} label: {
|
||||
Text("Disconnect")
|
||||
.font(Font.custom("ReadexPro-Bold", size: 14))
|
||||
.underline()
|
||||
.minimumScaleFactor(0.1)
|
||||
}
|
||||
|
||||
})
|
||||
|
|
@ -15,7 +15,7 @@ struct WifiSubViewCell: View {
|
|||
|
||||
@StateObject var wifiFileTransfer = WifiFileTransfer()
|
||||
@StateObject var wifiTransferService = WifiTransferService()
|
||||
let result : PyProject
|
||||
let result : ResultItem
|
||||
|
||||
@Binding var bindingString: String
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ Remove device from USB. Press "Reset" on the device.
|
|||
|
||||
|
||||
|
||||
func startOperationQueue() {
|
||||
func testOperation() {
|
||||
let operationQueue = OperationQueue()
|
||||
|
||||
let operation1 = BlockOperation {
|
||||
|
|
@ -157,18 +157,49 @@ Remove device from USB. Press "Reset" on the device.
|
|||
Text("Compatible with:")
|
||||
.font(Font.custom("ReadexPro-Bold", size: 18))
|
||||
.padding(.top, 5)
|
||||
|
||||
ForEach(result.compatibility, id: \.self) { device in
|
||||
HStack {
|
||||
Image(systemName: "checkmark")
|
||||
.resizable()
|
||||
.frame(width: 25, height: 22, alignment: .center)
|
||||
.foregroundColor(.green)
|
||||
Text(formatDeviceName(device))
|
||||
.font(Font.custom("ReadexPro-Regular", size: 18))
|
||||
.foregroundColor(.black)
|
||||
|
||||
HStack {
|
||||
Image(systemName: "checkmark")
|
||||
.resizable()
|
||||
.frame(width: 25, height: 22, alignment: .center)
|
||||
.foregroundColor(.green)
|
||||
Text("ESP32-S2")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 18))
|
||||
.foregroundColor(.black)
|
||||
}
|
||||
.padding(.top, 10)
|
||||
|
||||
|
||||
ForEach(result.compatibility, id: \.self) { string in
|
||||
if string == "circuitplayground_bluefruit" {
|
||||
|
||||
HStack {
|
||||
Image(systemName: "checkmark")
|
||||
.resizable()
|
||||
.frame(width: 25, height: 22, alignment: .center)
|
||||
.foregroundColor(.green)
|
||||
Text("Circuit Playground Bluefruit")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 18))
|
||||
.foregroundColor(.black)
|
||||
}
|
||||
.padding(.top, 10)
|
||||
}
|
||||
|
||||
|
||||
|
||||
if string == "clue_nrf52840_express" {
|
||||
|
||||
HStack {
|
||||
Image(systemName: "checkmark")
|
||||
.resizable()
|
||||
.frame(width: 25, height: 22, alignment: .center)
|
||||
.foregroundColor(.green)
|
||||
Text("Adafruit CLUE")
|
||||
.font(Font.custom("ReadexPro-Regular", size: 18))
|
||||
.foregroundColor(.black)
|
||||
}
|
||||
.padding(.top, 10)
|
||||
}
|
||||
.padding(.top, 10)
|
||||
}
|
||||
})
|
||||
.ignoresSafeArea(.all)
|
||||
|
|
@ -188,15 +219,18 @@ Remove device from USB. Press "Reset" on the device.
|
|||
|
||||
|
||||
|
||||
|
||||
if isConnected {
|
||||
|
||||
if result.compatibility.contains(bindingString) {
|
||||
|
||||
|
||||
if wifiFileTransfer.testIndex.downloadState == .idle {
|
||||
|
||||
|
||||
Button {
|
||||
// NotificationCenter.default.post(name: .didCompleteZip, object: nil, userInfo: projectResponse)
|
||||
|
||||
startOperationQueue()
|
||||
testOperation()
|
||||
|
||||
} label: {
|
||||
RunItButton()
|
||||
|
|
@ -236,8 +270,20 @@ Remove device from USB. Press "Reset" on the device.
|
|||
.disabled(true)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
Button {
|
||||
rootViewModel.goTobluetoothPairing()
|
||||
} label: {
|
||||
ConnectButton()
|
||||
.padding(.top, 20)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
|
@ -69,7 +69,32 @@ class WifiSubViewCellModel: ObservableObject {
|
|||
print("Failure")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// if success.contains("GET, OPTIONS, PUT, DELETE, MOVE") {
|
||||
//
|
||||
// print("USB not in use.")
|
||||
// DispatchQueue.main.async {
|
||||
// self.usbInUse = false
|
||||
// }
|
||||
//
|
||||
// // DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
// // if wifiFileTransfer.projectDownloaded {
|
||||
// //
|
||||
// // wifiFileTransfer.testFileExistance(for: result.projectName, bundleLink: result.bundleLink)
|
||||
// //
|
||||
// // } else {
|
||||
// // downloadModel.trueDownload(useProject: result.bundleLink, projectName: result.projectName)
|
||||
// // }
|
||||
// // }
|
||||
//
|
||||
// } else {
|
||||
// DispatchQueue.main.async {
|
||||
// self.usbInUse = true
|
||||
// }
|
||||
// print("USB in use - files cannot be tranferred or moved while USB is in use. Show Error")
|
||||
// }
|
||||
|
||||
})
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ class WifiTransferService: ObservableObject {
|
|||
}
|
||||
let base64LoginString = loginData.base64EncodedString()
|
||||
|
||||
|
||||
// var request = URLRequest(url: URL(string: "http://cpy-9cbe10.local/fs/")!,timeoutInterval: Double.infinity)
|
||||
var request = URLRequest(url: URL(string: "http://\(hostName).local/fs/")!,timeoutInterval: Double.infinity)
|
||||
|
||||
request.addValue("application/json", forHTTPHeaderField: "Accept")
|
||||
|
|
@ -226,6 +226,7 @@ class WifiTransferService: ObservableObject {
|
|||
|
||||
let loginData = loginString.data(using: String.Encoding.utf8)
|
||||
|
||||
|
||||
let base64LoginString = loginData!.base64EncodedString()
|
||||
|
||||
print("Host Name: \(hostName)")
|
||||
|
|
@ -11,7 +11,7 @@ import Combine
|
|||
|
||||
struct WifiView: View {
|
||||
|
||||
@StateObject var vm = WifiViewModel()
|
||||
@StateObject var viewModel = WifiViewModel()
|
||||
private let kPrefix = Bundle.main.bundleIdentifier!
|
||||
|
||||
// User Defaults
|
||||
|
|
@ -38,12 +38,12 @@ struct WifiView: View {
|
|||
@State private var showPopover: Bool = false
|
||||
|
||||
func toggleViewModelIP() {
|
||||
vm.isInvalidIP.toggle()
|
||||
viewModel.isInvalidIP.toggle()
|
||||
}
|
||||
|
||||
|
||||
func scanNetworkWifi() {
|
||||
vm.wifiServiceManager.findService()
|
||||
viewModel.wifiServiceManager.findService()
|
||||
}
|
||||
|
||||
func printArray(array: [Any]) {
|
||||
|
|
@ -59,9 +59,9 @@ struct WifiView: View {
|
|||
|
||||
} else {
|
||||
hostName = userDefaults.object(forKey: kPrefix+".storeResolvedAddress.hostName") as! String
|
||||
vm.ipAddressStored = true
|
||||
viewModel.ipAddressStored = true
|
||||
print("storeResolvedAddress - is stored")
|
||||
vm.connectionStatus = .connected
|
||||
viewModel.connectionStatus = .connected
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,40 +71,28 @@ struct WifiView: View {
|
|||
hintText: "IP Address...",
|
||||
primaryTitle: "Done",
|
||||
secondaryTitle: "Cancel") { text in
|
||||
vm.checkServices(ip: text)
|
||||
viewModel.checkServices(ip: text)
|
||||
|
||||
} secondaryAction: {
|
||||
print("Cancel")
|
||||
}
|
||||
}
|
||||
|
||||
func showConfirmationPrompt() {
|
||||
comfirmationAlertMessage(title: "Are you sure you want to disconnect?", exitTitle: "Cancel", primaryTitle: "Disconnect") {
|
||||
rootViewModel.goToSelection()
|
||||
} cancel: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func showAlertMessage() {
|
||||
alertMessage(title: "IP address Not Found", exitTitle: "Ok") {
|
||||
showValidationPrompt()
|
||||
}
|
||||
}
|
||||
|
||||
@State var boardInfoForView = Board.shared
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack(spacing: 0) {
|
||||
WifiHeaderView()
|
||||
|
||||
Group{
|
||||
switch vm.connectionStatus {
|
||||
switch viewModel.connectionStatus {
|
||||
case .connected:
|
||||
WifiStatusConnectedView(hostName: $hostName, disconnectAction: {
|
||||
showConfirmationPrompt()
|
||||
})
|
||||
WifiStatusConnectedView(hostName: $hostName)
|
||||
case .noConnection:
|
||||
WifiStatusNoConnectionView()
|
||||
case .connecting:
|
||||
|
|
@ -112,14 +100,16 @@ struct WifiView: View {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
|
||||
ScrollViewReader { scroll in
|
||||
|
||||
SubHeaderView()
|
||||
|
||||
let check = vm.pdemos.filter {
|
||||
$0.wifiCompatible
|
||||
|
||||
|
||||
let check = viewModel.pdemos.filter {
|
||||
$0.compatibility.contains(boardBootInfo)
|
||||
}
|
||||
|
||||
ForEach(check) { demo in
|
||||
|
|
@ -127,43 +117,48 @@ struct WifiView: View {
|
|||
if demo.bundleLink == test.currentCell {
|
||||
WifiCell(result: demo,isExpanded: trueTog, isConnected: $inConnectedInWifiView, bootOne: $boardBootInfo, stateBinder: $downloadState, onViewGeometryChanged: {
|
||||
|
||||
|
||||
})
|
||||
.onAppear(){
|
||||
|
||||
withAnimation {
|
||||
scroll.scrollTo(demo.id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
WifiCell(result: demo, isExpanded: falseTog, isConnected: $inConnectedInWifiView, bootOne: $boardBootInfo, stateBinder: $downloadState, onViewGeometryChanged: {
|
||||
withAnimation {
|
||||
// scroll.scrollTo(demo.id)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.id(self.scrollViewID)
|
||||
}
|
||||
.foregroundColor(.black)
|
||||
.environmentObject(test)
|
||||
.refreshable {
|
||||
vm.fetchAndLoadProjectsFromStorage()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.onChange(of: vm.connectionStatus, perform: { newValue in
|
||||
.onChange(of: viewModel.connectionStatus, perform: { newValue in
|
||||
if newValue == .connected {
|
||||
hostName = userDefaults.object(forKey: kPrefix+".storeResolvedAddress.hostName") as! String
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
.onChange(of: vm.wifiServiceManager.resolvedServices, perform: { newValue in
|
||||
.onChange(of: viewModel.wifiServiceManager.resolvedServices, perform: { newValue in
|
||||
print("Credential Check!")
|
||||
print(newValue)
|
||||
|
||||
|
|
@ -178,7 +173,7 @@ struct WifiView: View {
|
|||
|
||||
})
|
||||
|
||||
.onChange(of: vm.isInvalidIP, perform: { newValue in
|
||||
.onChange(of: viewModel.isInvalidIP, perform: { newValue in
|
||||
print("viewModel.isInvalidIP .onChange")
|
||||
if newValue {
|
||||
showAlertMessage()
|
||||
|
|
@ -190,8 +185,8 @@ struct WifiView: View {
|
|||
|
||||
.onAppear(){
|
||||
checkForStoredIPAddress()
|
||||
vm.printStoredInfo()
|
||||
vm.read()
|
||||
viewModel.printStoredInfo()
|
||||
viewModel.read()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +27,6 @@ class WifiViewModel: ObservableObject {
|
|||
@Published var ipInputValidation = false
|
||||
//Dependencies
|
||||
var networkMonitor = NetworkMonitor()
|
||||
|
||||
var networkAuth = LocalNetworkAuthorization()
|
||||
|
||||
public var wifiNetworkService = WifiNetworkService()
|
||||
|
|
@ -35,7 +34,7 @@ class WifiViewModel: ObservableObject {
|
|||
@Published var wifiTransferService = WifiTransferService()
|
||||
|
||||
@Published var wifiServiceManager = WifiServiceManager()
|
||||
@ObservedObject var networkModel = NetworkService()
|
||||
|
||||
var circuitPythonVersion = Int()
|
||||
|
||||
@Published var webDirectoryInfo = [WebDirectoryModel]()
|
||||
|
|
@ -46,19 +45,9 @@ class WifiViewModel: ObservableObject {
|
|||
|
||||
let dataStore = DataStore()
|
||||
|
||||
@Published var pdemos : [PyProject] = []
|
||||
@Published var pdemos : [ResultItem] = []
|
||||
|
||||
|
||||
func loadProjectsFromStorage() {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
|
||||
func fetchAndLoadProjectsFromStorage() {
|
||||
self.networkModel.fetch {
|
||||
self.pdemos = self.dataStore.loadDefaultList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// File Manager Data
|
||||
let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
|
|
@ -70,10 +59,11 @@ class WifiViewModel: ObservableObject {
|
|||
var ipAddressStored = false
|
||||
|
||||
init() {
|
||||
loadProjectsFromStorage()
|
||||
pdemos = dataStore.loadDefaultList()
|
||||
checkIP()
|
||||
registerNotifications(enabled: true)
|
||||
wifiServiceManager.findService()
|
||||
//read()
|
||||
}
|
||||
|
||||
/// Makes a network call to populate our project list
|
||||
|
|
@ -81,37 +71,27 @@ class WifiViewModel: ObservableObject {
|
|||
// networkModel.fetch()
|
||||
}
|
||||
|
||||
@Published var pyleapProjects = [PyProject]()
|
||||
|
||||
var boardDataProvider = BoardDataProvider()
|
||||
|
||||
|
||||
// This function reads the boards the boot_out.txt file to then set the current board's name and version number for file transfer.
|
||||
|
||||
func setBoardToDefault() {
|
||||
Board.shared.name = "Unrecognized Board"
|
||||
Board.shared.versionNumber = "8"
|
||||
}
|
||||
@Published var pyleapProjects = [ResultItem]()
|
||||
|
||||
|
||||
func read() {
|
||||
setBoardToDefault()
|
||||
// This method can't be used until the device has permission to communicate.
|
||||
print("READING CP Vers.")
|
||||
wifiTransferService.getRequest(read: "boot_out.txt") { result in
|
||||
|
||||
let boardID = self.boardDataProvider.getBoardID(from: result) ?? "Unrecognized Board"
|
||||
// Board default version is set to 8
|
||||
let boardVersion = self.boardDataProvider.getCircuitPythonMajorVersion(from: result) ?? "8"
|
||||
|
||||
Board.shared.name = boardID
|
||||
Board.shared.versionNumber = boardVersion
|
||||
dump(Board.shared)
|
||||
if result.contains("CircuitPython 7") {
|
||||
WifiCPVersion.versionNumber = 7
|
||||
print("WifiCPVersion.versionNumber set to: \(WifiCPVersion.versionNumber)")
|
||||
}
|
||||
|
||||
if result.contains("CircuitPython 8") {
|
||||
WifiCPVersion.versionNumber = 8
|
||||
print("WifiCPVersion.versionNumber set to: \(WifiCPVersion.versionNumber)")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private weak var invalidIPObserver: NSObjectProtocol?
|
||||
|
|
@ -166,7 +146,12 @@ class WifiViewModel: ObservableObject {
|
|||
connectionStatus = .connected
|
||||
}
|
||||
|
||||
// @Published var connectionStatus: ConnectionStatus = AppEnvironment.isRunningTests ? .connected : .noConnection
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func printStoredInfo() {
|
||||
print("======Stored UserDefaults======")
|
||||
|
||||
Loading…
Reference in a new issue