Merge pull request #1003 from meshtastic/2.5.11

Handle connsecutive capital letters in camelCaseToWords function
This commit is contained in:
Garth Vander Houwen 2024-12-13 20:38:22 -08:00 committed by GitHub
commit b775fb345d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
113 changed files with 3896 additions and 172 deletions

View file

@ -9017,7 +9017,7 @@
}
},
"incomplete" : {
"extractionState" : "migrated",
"extractionState" : "manual",
"localizations" : {
"de" : {
"stringUnit" : {
@ -15216,6 +15216,9 @@
}
}
}
},
"Model" : {
},
"module.configuration" : {
"localizations" : {
@ -23713,18 +23716,15 @@
}
}
},
"Version %@ includes breaking changes to devices and the client apps. Only nodes version %@ and above are supported." : {
"Version %@ includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version %@ and above are supported." : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Version %1$@ includes breaking changes to devices and the client apps. Only nodes version %2$@ and above are supported."
"value" : "Version %1$@ includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version %2$@ and above are supported."
}
}
}
},
"Version 1.2 End of life (EOL) Info" : {
},
"Version: %@ (%@) " : {
"localizations" : {
@ -24065,4 +24065,4 @@
}
},
"version" : "1.0"
}
}

View file

@ -1704,7 +1704,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.5.10;
MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1738,7 +1738,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.5.10;
MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1770,7 +1770,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.5.10;
MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1803,7 +1803,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.5.10;
MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "LILYGO-TTGO-LoRa32-V2-1-1-6-Version-433-868-915Mhz-ESP32-LoRa-OLED-0-96.jpg_Q90.jpg_.webp.png",
"filename" : "heltec-ht62-esp32c3-sx1262.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 62 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "heltec-mesh-node-t114-case.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="795.27 277.13 409.46 1319.35"><defs><style>.cls-1{fill:#353535;}.cls-2{fill:#1e1e1d;}.cls-3{fill:#b1a368;}.cls-10,.cls-11,.cls-4,.cls-6,.cls-8,.cls-9{fill:none;}.cls-4,.cls-6{stroke:#050606;}.cls-10,.cls-11,.cls-4,.cls-6,.cls-8{stroke-miterlimit:10;}.cls-4{stroke-width:2.41px;}.cls-5{fill:#30c2db;}.cls-6{stroke-width:3.91px;}.cls-7{fill:#dcf0f2;}.cls-10,.cls-11,.cls-8{stroke:#dcf0f2;}.cls-8{stroke-width:1.81px;}.cls-9{stroke:#17afbf;stroke-linecap:round;stroke-linejoin:round;stroke-width:7.23px;}.cls-10{stroke-width:1.78px;}.cls-11{stroke-width:1.81px;}</style></defs><g id="Layer_7" data-name="Layer 7"><path class="cls-1" d="M915.62,278.34h22.61a35,35,0,0,1,35,35V715.74a0,0,0,0,1,0,0H880.6a0,0,0,0,1,0,0V313.36A35,35,0,0,1,915.62,278.34Z"></path><rect class="cls-2" x="880.6" y="340.15" width="92.65" height="7.54"></rect><rect class="cls-2" x="880.6" y="356.68" width="92.65" height="7.54"></rect><rect class="cls-3" x="885.8" y="844.3" width="84.14" height="19.02"></rect><rect class="cls-3" x="880.6" y="819.07" width="92.65" height="25.23"></rect><rect class="cls-3" x="885.8" y="790.65" width="84.14" height="28.41"></rect><rect class="cls-3" x="880.6" y="723.02" width="92.65" height="67.63"></rect><rect class="cls-3" x="885.8" y="715.74" width="84.14" height="7.28"></rect><rect class="cls-4" x="885.8" y="844.3" width="84.14" height="19.02"></rect><rect class="cls-4" x="880.6" y="819.07" width="92.65" height="25.23"></rect><rect class="cls-4" x="885.8" y="790.65" width="84.14" height="28.41"></rect><rect class="cls-4" x="880.6" y="723.02" width="92.65" height="67.63"></rect><rect class="cls-4" x="885.8" y="715.74" width="84.14" height="7.28"></rect><path class="cls-4" d="M915.62,278.34h22.61a35,35,0,0,1,35,35V715.74a0,0,0,0,1,0,0H880.6a0,0,0,0,1,0,0V313.36A35,35,0,0,1,915.62,278.34Z"></path><rect class="cls-4" x="880.6" y="340.15" width="92.65" height="7.54"></rect><rect class="cls-4" x="880.6" y="356.68" width="92.65" height="7.54"></rect><rect class="cls-5" x="796.48" y="856.3" width="407.05" height="738.98" rx="47.74"></rect><rect class="cls-1" x="900.05" y="973.19" width="202.03" height="354.65" rx="16.4"></rect><rect class="cls-6" x="900.05" y="973.19" width="202.03" height="354.65" rx="16.4"></rect><rect class="cls-7" x="871.51" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><rect class="cls-7" x="1070.16" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><rect class="cls-4" x="871.51" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><rect class="cls-4" x="1070.16" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><circle class="cls-8" cx="841.7" cy="1537.01" r="16.25"></circle><circle class="cls-8" cx="841.7" cy="913.26" r="16.25"></circle><circle class="cls-8" cx="1157.32" cy="913.26" r="16.25"></circle><circle class="cls-8" cx="1157.32" cy="1504.51" r="16.25"></circle><line class="cls-9" x1="942.51" y1="1592.42" x2="942.51" y2="1381.55"></line><line class="cls-9" x1="966.52" y1="1592.42" x2="966.52" y2="1381.55"></line><line class="cls-9" x1="990.57" y1="1592.42" x2="990.57" y2="1381.55"></line><line class="cls-9" x1="1014.59" y1="1592.42" x2="1014.59" y2="1381.55"></line><line class="cls-9" x1="1038.63" y1="1592.42" x2="1038.63" y2="1381.55"></line><line class="cls-9" x1="1062.65" y1="1592.42" x2="1062.65" y2="1381.55"></line><rect class="cls-4" x="796.48" y="856.3" width="407.05" height="738.98" rx="47.74"></rect><path class="cls-10" d="M1040.1,947.74H960.65A13.93,13.93,0,0,1,947,936.64l-10.23-49.2a13.93,13.93,0,0,1,13.64-16.77h97.72a13.93,13.93,0,0,1,13.75,16.18l-8,49.2A13.94,13.94,0,0,1,1040.1,947.74Z"></path><rect class="cls-11" x="816.35" y="870.67" width="365.51" height="703.12" rx="32.37"></rect><rect class="cls-11" x="888.77" y="963.84" width="223.2" height="374.66" rx="25.21"></rect></g></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "Heltec_turq.png",
"filename" : "heltec-v3-case.svg",
"idiom" : "universal"
}
],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 MiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="404.68 390.65 1217.15 959.26"><defs><style>.cls-1{fill:#dfeaf7;}.cls-2{fill:#17907f;}.cls-3{fill:#2b2b2b;}.cls-4,.cls-5{fill:none;stroke:#050606;stroke-miterlimit:10;}.cls-4{stroke-width:2.25px;}.cls-5{stroke-width:4px;}.cls-6{fill:#050606;}</style></defs><g id="Layer_5" data-name="Layer 5"><path class="cls-1" d="M1517.73,392.65h0a102.1,102.1,0,0,0-102.1,102.1V770.37A40.62,40.62,0,0,1,1375,811H455.16a48.49,48.49,0,0,0-48.48,48.48v126a11.85,11.85,0,0,0,3.46,8.37l15.34,15.34a11.81,11.81,0,0,1,3.47,8.37v137.16a11.81,11.81,0,0,1-3.47,8.37l-15.34,15.34a11.85,11.85,0,0,0-3.46,8.37v112.67a48.49,48.49,0,0,0,48.48,48.49H1571.34a48.51,48.51,0,0,0,48.49-48.5V494.75A102.1,102.1,0,0,0,1517.73,392.65Zm-110.61,815V954a33.14,33.14,0,0,1,66.27,0v253.65a33.14,33.14,0,0,1-66.27,0Z"></path><path class="cls-2" d="M1516,439.16c-30.23.91-53.92,26.54-53.92,56.79V770.37A87.11,87.11,0,0,1,1375,857.48H732.31A27.51,27.51,0,0,0,704.8,885v388.93a27.51,27.51,0,0,0,27.51,27.51h828.38a12.7,12.7,0,0,0,12.65-12.65v-794A55.69,55.69,0,0,0,1516,439.16Zm-108.9,768.47V954a33.14,33.14,0,0,1,66.27,0v253.65a33.14,33.14,0,0,1-66.27,0Z"></path><rect class="cls-3" x="787.14" y="943.38" width="429.45" height="224.42"></rect><path class="cls-1" d="M1478.6,915.35A54.23,54.23,0,0,0,1386,953.69v254.23a54.23,54.23,0,1,0,108.45,0V953.69A54,54,0,0,0,1478.6,915.35Zm-5.21,292.28a33.14,33.14,0,0,1-66.27,0V954a33.14,33.14,0,0,1,66.27,0Z"></path></g><g id="Layer_2" data-name="Layer 2"><path class="cls-4" d="M1573.34,494.75v794a12.68,12.68,0,0,1-12.65,12.65H732.31a27.51,27.51,0,0,1-27.51-27.51V885a27.51,27.51,0,0,1,27.51-27.51H1375a87.11,87.11,0,0,0,87.11-87.11V496c0-30.25,23.69-55.88,53.92-56.79A55.69,55.69,0,0,1,1573.34,494.75Z"></path><path class="cls-5" d="M410.14,1178.39,425.49,1163a11.78,11.78,0,0,0,3.46-8.35V1017.5a11.8,11.8,0,0,0-3.46-8.35l-15.35-15.36a11.77,11.77,0,0,1-3.46-8.35v-126A48.47,48.47,0,0,1,455.16,811H1375a40.63,40.63,0,0,0,40.63-40.63V494.75a102.1,102.1,0,0,1,102.1-102.1h0a102.1,102.1,0,0,1,102.1,102.1v804.66a48.51,48.51,0,0,1-48.49,48.5H455.16a48.48,48.48,0,0,1-48.48-48.49V1186.74A11.78,11.78,0,0,1,410.14,1178.39Z"></path><rect class="cls-4" x="1407.12" y="920.85" width="66.26" height="319.9" rx="33.13"></rect><rect class="cls-4" x="1386.03" y="899.46" width="108.46" height="362.69" rx="54.23"></rect><path class="cls-6" d="M639.76,1070.55a2.91,2.91,0,0,1-2.91-2.91v-30.53a5.42,5.42,0,0,0-1.6-3.86l-32.44-32.44a11.86,11.86,0,0,1-3.5-8.44V901a12.52,12.52,0,0,0-12.51-12.51H483.92a12.7,12.7,0,0,0-12.68,12.69v76.78a24.13,24.13,0,0,0,7.11,17.18l14.33,14.33a24.13,24.13,0,0,0,17.18,7.11h50.75a11.86,11.86,0,0,1,8.44,3.5l24.26,24.26a12.47,12.47,0,0,1,3.68,8.88v14.46a2.91,2.91,0,1,1-5.81,0v-14.46a6.72,6.72,0,0,0-2-4.77l-24.26-24.26a6.09,6.09,0,0,0-4.33-1.8H509.86a29.91,29.91,0,0,1-21.29-8.81l-14.33-14.33a29.87,29.87,0,0,1-8.81-21.29V901.14a18.51,18.51,0,0,1,18.49-18.5H586.8A18.34,18.34,0,0,1,605.12,901v91.41a6.09,6.09,0,0,0,1.8,4.33l32.44,32.44a11.19,11.19,0,0,1,3.3,8v30.53A2.9,2.9,0,0,1,639.76,1070.55Z"></path><path class="cls-6" d="M586.8,1289.46H483.92a18.51,18.51,0,0,1-18.49-18.5v-76.78a29.87,29.87,0,0,1,8.81-21.29l14.33-14.34a29.91,29.91,0,0,1,21.29-8.81h50.75a6.09,6.09,0,0,0,4.33-1.8l24.26-24.25a6.74,6.74,0,0,0,2-4.78v-14.46a2.91,2.91,0,0,1,5.81,0v14.46a12.51,12.51,0,0,1-3.68,8.89l-24.26,24.25a11.86,11.86,0,0,1-8.44,3.5H509.86a24.17,24.17,0,0,0-17.18,7.11L478.35,1177a24.09,24.09,0,0,0-7.11,17.18V1271a12.71,12.71,0,0,0,12.68,12.69H586.8a12.53,12.53,0,0,0,12.51-12.52v-91.4a11.83,11.83,0,0,1,3.5-8.44l32.44-32.44a5.46,5.46,0,0,0,1.6-3.87v-30.53a2.91,2.91,0,0,1,5.81,0V1135a11.19,11.19,0,0,1-3.3,8l-32.44,32.45a6.06,6.06,0,0,0-1.8,4.33v91.4A18.35,18.35,0,0,1,586.8,1289.46Z"></path><rect class="cls-4" x="787.14" y="943.38" width="429.45" height="224.42"></rect></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "heltec-vision-master-e213.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="528.89 806.04 942.22 446.84"><defs><style>.cls-1{fill:#e8eae8;}.cls-2{fill:#dbdddb;}.cls-3{fill:#c6842a;}.cls-4,.cls-5,.cls-7,.cls-9{fill:none;stroke-miterlimit:10;}.cls-4,.cls-5{stroke:#050606;}.cls-4,.cls-9{stroke-width:2.44px;}.cls-5,.cls-7{stroke-width:1.22px;}.cls-6{fill:#b7b7b7;}.cls-7,.cls-9{stroke:#b7b7b7;}.cls-8{fill:#cbcccb;}.cls-10{fill:#434543;}</style></defs><g id="Layer_4" data-name="Layer 4"><path class="cls-1" d="M1469.9,826.68v390.94a19.43,19.43,0,0,1-19.43,19.43H549.53a19.43,19.43,0,0,1-19.43-19.43V826.68a19.42,19.42,0,0,1,19.43-19.42h900.94A19.42,19.42,0,0,1,1469.9,826.68Z"></path><path class="cls-2" d="M574.23,807.26v429.79h-24.7a19.43,19.43,0,0,1-19.43-19.43V826.68a19.42,19.42,0,0,1,19.43-19.42Z"></path><path class="cls-2" d="M1469.9,826.68v390.94a19.43,19.43,0,0,1-19.43,19.43h-37.56V807.26h37.56A19.42,19.42,0,0,1,1469.9,826.68Z"></path><path class="cls-3" d="M574.23,1129.8h-7.47a4.55,4.55,0,0,1-4.55-4.54V919.05a4.55,4.55,0,0,1,4.55-4.55h7.47"></path><rect class="cls-4" x="530.11" y="807.26" width="939.78" height="429.79" rx="19.42"></rect><line class="cls-5" x1="574.23" y1="807.26" x2="574.23" y2="1237.05"></line><path class="cls-5" d="M574.23,1129.8h-7.47a4.55,4.55,0,0,1-4.55-4.54V919.05a4.55,4.55,0,0,1,4.55-4.55h7.47"></path><rect class="cls-6" x="599.01" y="970.1" width="11.52" height="104.11"></rect><rect class="cls-5" x="599.01" y="970.1" width="11.52" height="104.11"></rect><path class="cls-2" d="M610.53,816.78V935.32l38.37,11.55a7.85,7.85,0,0,1,5.6,7.53V1107a7.87,7.87,0,0,1-7.87,7.87h-36.1v110.58H1406V816.78Zm775.41,384.75H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66h754.51Z"></path><path class="cls-1" d="M1385.94,840.45v361.08H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66Z"></path><path class="cls-7" d="M610.53,816.78V935.32l38.37,11.55a7.85,7.85,0,0,1,5.6,7.53V1107a7.87,7.87,0,0,1-7.87,7.87h-36.1v110.58H1406V816.78Zm775.41,384.75H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66h754.51Z"></path><path class="cls-7" d="M1385.94,840.45v361.08H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66Z"></path><path class="cls-7" d="M1385.94,840.45v361.08H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66Z"></path><line class="cls-7" x1="666.4" y1="1132.79" x2="666.4" y2="1201.53"></line><line class="cls-7" x1="663.66" y1="916.86" x2="663.66" y2="840.45"></line><circle class="cls-8" cx="644.99" cy="878.66" r="10.7"></circle><circle class="cls-8" cx="644.99" cy="1171.55" r="10.7"></circle><circle class="cls-9" cx="644.99" cy="878.66" r="10.7"></circle><circle class="cls-9" cx="644.99" cy="1171.55" r="10.7"></circle><path class="cls-10" d="M1225,1237.05l2.23,11.19a4.25,4.25,0,0,0,4.17,3.42H1249a4.26,4.26,0,0,0,4.18-3.42l2.22-11.19"></path><path class="cls-10" d="M1306.87,1237.05l2.22,11.19a4.26,4.26,0,0,0,4.18,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.22-11.19"></path><path class="cls-10" d="M1388.77,1237.05l2.23,11.19a4.24,4.24,0,0,0,4.17,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.23-11.19"></path><path class="cls-4" d="M1225,1237.05l2.23,11.19a4.25,4.25,0,0,0,4.17,3.42H1249a4.26,4.26,0,0,0,4.18-3.42l2.22-11.19"></path><path class="cls-4" d="M1306.87,1237.05l2.22,11.19a4.26,4.26,0,0,0,4.18,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.22-11.19"></path><path class="cls-4" d="M1388.77,1237.05l2.23,11.19a4.24,4.24,0,0,0,4.17,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.23-11.19"></path><line class="cls-4" x1="1412.9" y1="807.26" x2="1412.9" y2="1237.05"></line></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "heltec-vision-master-e290.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "Paper-Meshtastic-2 copy.jpg",
"filename" : "heltec-wireless-paper.svg",
"idiom" : "universal"
}
],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "images.png",
"filename" : "heltec-wireless-tracker.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "heltecwsl.png",
"filename" : "heltec-wsl-v3.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "tbeam_supreme.png",
"filename" : "tbeam-s3-core.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 MiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "nano_g2_ultra_product_image.jpg",
"filename" : "nano-g2-ultra.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "RAK_DEV_KIT-2.jpg",
"filename" : "promicro.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "TLORA_olive 1.png",
"filename" : "rak11310.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 58 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "RAK 4.png",
"filename" : "rak4631_case.svg",
"idiom" : "universal"
}
],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "pico.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "seeed-xiao-s3.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "seeed-sensecap-indicator.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "station-g2.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "tbeam.png",
"filename" : "tbeam.svg",
"idiom" : "universal"
}
],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 112 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "t-deck.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "LILYGO-TTGO-SoftRF-T-Echo-NRF52840-LoRa-SX1262-433-868-915MHz-Wireless-Module-L76K-GPS-1.png",
"filename" : "t-echo.svg",
"idiom" : "universal"
}
],

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tlora-c6.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tlora-t3s3-epaper.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tlora-t3s3-v1.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 MiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tlora-v2-1-1_6.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tlora-v2-1-1_8.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tracker-t1000-e.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "t-watch-s3.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="733.42 451.82 573.87 931.48"><defs><style>.cls-1{fill:#8e8d8e;}.cls-2{fill:#383839;}.cls-3{fill:#cccccb;}.cls-4{fill:#222226;}.cls-5,.cls-6{fill:none;stroke:#050606;stroke-miterlimit:10;}.cls-5{stroke-width:1.87px;}.cls-6{stroke-width:3.77px;}.cls-7{fill:#4c4c4d;}</style></defs><g id="Layer_4" data-name="Layer 4"><path class="cls-1" d="M1277.27,847.59h4.35a8.09,8.09,0,0,1,8.09,8.08v138a8.09,8.09,0,0,1-8.09,8.09h-4.35"></path><path class="cls-1" d="M1277.27,732.73h18a10.14,10.14,0,0,1,10.14,10.14v43A10.14,10.14,0,0,1,1295.26,796h-18a0,0,0,0,1,0,0V732.73A0,0,0,0,1,1277.27,732.73Z"></path><path class="cls-2" d="M1256.49,1200.6h0a14.19,14.19,0,0,1-2.83,12.5c-8.13,9.86-19.94,18.58-46,30.75-19.15,9-28.65,16-38.35,29.6a93.15,93.15,0,0,0-8.7,14.61c-6.95,15.17-11.77,44.44-11.77,65.66v3.61a24.09,24.09,0,0,1-24.1,24.09H887.83a24.09,24.09,0,0,1-24.1-24.09v-3.61c0-21.22-4.82-50.49-11.77-65.66a93.15,93.15,0,0,0-8.7-14.61c-9.7-13.63-19.2-20.65-38.35-29.6-26.06-12.17-37.87-20.89-46-30.75a14.22,14.22,0,0,1-2.82-12.5h0"></path><path class="cls-2" d="M756.09,634.53h0a14.19,14.19,0,0,1,2.83-12.5c8.12-9.86,19.93-18.58,46-30.75,19.15-8.95,28.65-16,38.35-29.6a93.15,93.15,0,0,0,8.7-14.61c6.95-15.17,11.77-44.44,11.77-65.66V477.8a24.09,24.09,0,0,1,24.1-24.09h236.92a24.09,24.09,0,0,1,24.1,24.09v3.61c0,21.22,4.82,50.49,11.77,65.66a93.15,93.15,0,0,0,8.7,14.61c9.7,13.63,19.2,20.65,38.35,29.6,26,12.17,37.86,20.89,46,30.75a14.19,14.19,0,0,1,2.83,12.5h0"></path><rect class="cls-3" x="735.31" y="598.25" width="541.96" height="638.99" rx="96.44"></rect><path class="cls-2" d="M1247.38,694.68v446.11a66.63,66.63,0,0,1-66.54,66.56H831.75a66.62,66.62,0,0,1-66.56-66.56V694.68a66.63,66.63,0,0,1,66.56-66.55h349.09A66.64,66.64,0,0,1,1247.38,694.68Z"></path><rect class="cls-4" x="817.71" y="721.76" width="379.03" height="388.6"></rect><path class="cls-5" d="M1247.38,694.68v446.11a66.63,66.63,0,0,1-66.54,66.56H831.75a66.62,66.62,0,0,1-66.56-66.56V694.68a66.63,66.63,0,0,1,66.56-66.55h349.09A66.64,66.64,0,0,1,1247.38,694.68Z"></path><rect class="cls-6" x="735.31" y="598.25" width="541.96" height="638.99" rx="96.44"></rect><path class="cls-6" d="M1256.49,1200.6h0a14.19,14.19,0,0,1-2.83,12.5c-8.13,9.86-19.94,18.58-46,30.75-19.15,9-28.65,16-38.35,29.6a93.15,93.15,0,0,0-8.7,14.61c-6.95,15.17-11.77,44.44-11.77,65.66v3.61a24.09,24.09,0,0,1-24.1,24.09H887.83a24.09,24.09,0,0,1-24.1-24.09v-3.61c0-21.22-4.82-50.49-11.77-65.66a93.15,93.15,0,0,0-8.7-14.61c-9.7-13.63-19.2-20.65-38.35-29.6-26.06-12.17-37.87-20.89-46-30.75a14.22,14.22,0,0,1-2.82-12.5h0"></path><path class="cls-6" d="M756.09,634.53h0a14.19,14.19,0,0,1,2.83-12.5c8.12-9.86,19.93-18.58,46-30.75,19.15-8.95,28.65-16,38.35-29.6a93.15,93.15,0,0,0,8.7-14.61c6.95-15.17,11.77-44.44,11.77-65.66V477.8a24.09,24.09,0,0,1,24.1-24.09h236.92a24.09,24.09,0,0,1,24.1,24.09v3.61c0,21.22,4.82,50.49,11.77,65.66a93.15,93.15,0,0,0,8.7,14.61c9.7,13.63,19.2,20.65,38.35,29.6,26,12.17,37.86,20.89,46,30.75a14.19,14.19,0,0,1,2.83,12.5h0"></path><rect class="cls-5" x="817.71" y="721.76" width="379.03" height="388.6"></rect><path class="cls-6" d="M1277.27,847.59h4.35a8.09,8.09,0,0,1,8.09,8.08v138a8.09,8.09,0,0,1-8.09,8.09h-4.35"></path><path class="cls-6" d="M1277.27,732.73h18a10.14,10.14,0,0,1,10.14,10.14v43A10.14,10.14,0,0,1,1295.26,796h-18a0,0,0,0,1,0,0V732.73A0,0,0,0,1,1277.27,732.73Z"></path><circle class="cls-7" cx="1083.08" cy="1177.35" r="16.6"></circle><rect class="cls-2" x="1280.24" y="739.77" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="750.91" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="762.06" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="773.2" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="784.34" width="16.77" height="4.59" rx="2.29"></rect></g></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "play_store_icon_114px-2.png",
"filename" : "unknown.svg",
"idiom" : "universal"
}
],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
class="svg-icon"
style="overflow:hidden;fill:currentColor"
viewBox="0 0 909.87988 546.85529"
version="1.1"
id="svg3"
xml:space="preserve"
width="909.87988"
height="546.85529"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs3"><style
id="style1">.cls-1{fill:#383838;}.cls-2{fill:#9f9f9e;}.cls-3{fill:#cbcccb;}.cls-4{fill:#b7b7b7;}.cls-5{fill:#353535;}.cls-6{fill:#b1a368;}.cls-7{fill:#2c2d2d;}.cls-10,.cls-11,.cls-8,.cls-9{fill:none;stroke:#050606;}.cls-10,.cls-11,.cls-8{stroke-miterlimit:10;}.cls-8,.cls-9{stroke-width:2px;}.cls-9{stroke-linecap:round;stroke-linejoin:round;}.cls-10{stroke-width:2.04px;}.cls-11{stroke-width:1.99px;}.cls-12{fill:#c08c2d;}.cls-13{fill:#af7a2b;}</style></defs><g
id="Layer_7"
data-name="Layer 7"
transform="translate(-646.6554,-758.05941)"><path
class="cls-2"
d="m 1545.1753,893.49468 h 4.69 a 5.67,5.67 0 0 1 5.67,5.67 v 84.64998 a 5.67,5.67 0 0 1 -5.67,5.67 h -4.69"
id="path1-4" /><rect
class="cls-3"
x="647.6554"
y="862.80469"
width="897.52002"
height="441.10999"
rx="11.7"
id="rect2" /><path
class="cls-2"
d="m 681.12532,862.80468 v 113.47998 a 3.67,3.67 0 0 0 3.67,3.67 h 41 a 2.35,2.35 0 0 1 2.35,2.35 V 1303.9147 H 1517.6053 V 862.80468 Z M 1492.6453,1278.9147 H 753.18532 V 972.01466 a 17.06,17.06 0 0 0 -17.06,-17.06 h -27.5 a 2.5,2.5 0 0 1 -2.5,-2.5 v -62.14998 a 2.5,2.5 0 0 1 2.5,-2.5 h 783.99998 z"
id="path2-7" /><path
class="cls-3"
d="M 1492.6453,887.80468 V 1278.9147 H 753.18532 V 972.01466 a 17,17 0 0 0 -7.2,-13.92 v -70.28998 z"
id="path3-7" /><path
class="cls-4"
d="m 745.98532,887.80468 v 70.28998 a 17,17 0 0 0 -9.86,-3.14 h -27.5 a 2.5,2.5 0 0 1 -2.5,-2.5 v -62.14998 a 2.5,2.5 0 0 1 2.5,-2.5 z"
id="path4" /><rect
class="cls-2"
x="672.10535"
y="1011.4448"
width="13.53"
height="148.39999"
id="rect4" /><path
class="cls-6"
d="m 1077.2923,853.76468 h 71.71 a 2.55,2.55 0 0 1 2.55,2.55 v 6.48 h -76.8 v -6.48 a 2.55,2.55 0 0 1 2.54,-2.55 z"
id="path7" /><path
class="cls-8"
d="m 1082.9205,761.22647 h 60.8838 a 6.1958134,4.8451518 0 0 1 6.1958,4.84516 v 77.32638 h -73.2754 v -77.32638 a 6.1958134,4.8451518 0 0 1 6.1958,-4.84516 z"
id="path39"
style="fill:#b1a368" /><rect
class="cls-8"
x="1066.9833"
y="778.19855"
width="91.504646"
height="55.957298"
rx="5.5511622"
id="rect39"
style="fill:#b1a368" /><path
class="cls-2"
d="m 1158.4522,782.53954 v 47.24724 a 5.5153484,4.3130254 0 0 1 -5.5512,4.34102 h -80.3665 a 5.5511623,4.341032 0 0 1 -5.587,-4.34102 v -47.24724 a 5.5511623,4.341032 0 0 1 5.587,-4.34103 h 80.5098 a 5.5153484,4.3130254 0 0 1 5.4079,4.34103 z"
id="path41-4"
style="fill:none;stroke:#050606;stroke-width:3.16706;stroke-miterlimit:10" /><rect
class="cls-6"
x="1079.9424"
y="843.73468"
width="65.989998"
height="10.03"
id="rect8" /><path
class="cls-8"
d="M 1492.6453,887.80468 V 1278.9147 H 753.18532 V 972.01466 a 17.06,17.06 0 0 0 -17.06,-17.06 h -27.5 a 2.5,2.5 0 0 1 -2.5,-2.5 v -62.14998 a 2.5,2.5 0 0 1 2.5,-2.5 h 783.99998 m 25,-25 H 681.12532 v 113.47998 a 3.68,3.68 0 0 0 3.67,3.67 h 41 a 2.35,2.35 0 0 1 2.35,2.35 V 1303.9147 H 1517.6053 V 862.80468 Z"
id="path10" /><line
class="cls-8"
x1="745.99536"
y1="958.09467"
x2="745.99536"
y2="887.80469"
id="line10" /><rect
class="cls-8"
x="672.10535"
y="1011.4448"
width="13.53"
height="148.39999"
id="rect11" /><path
class="cls-8"
d="m 1545.1753,893.49468 h 4.69 a 5.67,5.67 0 0 1 5.67,5.67 v 84.64998 a 5.67,5.67 0 0 1 -5.67,5.67 h -4.69"
id="path14" /><path
class="cls-10"
d="m 1077.2923,853.76468 h 71.71 a 2.55,2.55 0 0 1 2.55,2.55 v 6.48 h -76.8 v -6.48 a 2.55,2.55 0 0 1 2.54,-2.55 z"
id="path16" /><rect
class="cls-11"
x="1079.9424"
y="843.73468"
width="65.989998"
height="10.03"
id="rect17" /><path
class="cls-2"
d="m 725.27532,910.38466 a 14,14 0 1 0 14,14 13.95,13.95 0 0 0 -14,-14 z m 0,21.5 a 7.55,7.55 0 1 1 7.54,-7.55 7.55,7.55 0 0 1 -7.54,7.55 z"
id="path19" /><circle
class="cls-8"
cx="725.27539"
cy="924.33466"
r="7.5500002"
id="circle19" /><circle
class="cls-8"
cx="725.27539"
cy="924.33466"
r="13.95"
id="circle20" /><path
d="m 445.36309,440.05365 c 0,11.52004 10.38375,20.85861 23.19309,20.85861 12.80937,0 23.19311,-9.33857 23.19311,-20.85861 0,-11.52005 -10.38374,-20.85861 -23.19311,-20.85861 -12.80934,0 -23.19309,9.33856 -23.19309,20.85861 z"
fill="#ccc"
id="path1"
style="overflow:hidden;fill:#4d4d4d;stroke-width:0.458227"
transform="translate(646.6554,758.05941)" /><path
d="m 469.40305,538.40107 c -119.83415,0 -217.31582,-93.40624 -217.31582,-208.23067 0,-114.82425 97.48167,-208.23058 217.31582,-208.23058 119.83417,0 217.31585,93.40633 217.31585,208.23058 0,114.82443 -97.48168,208.23067 -217.31585,208.23067 z m 0,-386.58065 c -102.63515,0 -186.13149,80.00572 -186.13149,178.34998 0,98.32948 83.49634,178.34997 186.13149,178.34997 102.61966,0 186.13151,-80.01997 186.13151,-178.34997 0,-98.34426 -83.51185,-178.34998 -186.13151,-178.34998 z"
fill="#ccc"
id="path2"
style="overflow:hidden;fill:#4d4d4d;stroke-width:0.474832"
transform="translate(646.6554,758.05941)" /><path
d="m 468.55618,391.96713 c -8.53552,0 -15.46205,-6.22977 -15.46205,-13.90533 v -23.51468 c 0,-22.75028 19.32709,-40.13201 36.39722,-55.47009 12.50833,-11.26363 25.45056,-22.88885 25.45056,-32.16398 0,-23.18095 -20.81195,-42.03718 -46.38573,-42.03718 -26.0067,0 -46.38619,18.0497 -46.38619,41.09158 0,7.67594 -6.92654,13.90533 -15.46208,13.90533 -8.53554,0 -15.46207,-6.22977 -15.46207,-13.9058 0,-37.99002 34.68046,-68.90262 77.31034,-68.90262 42.62989,0 77.31034,31.32967 77.31034,69.84869 0,20.81694 -17.54944,36.5856 -34.51132,51.84064 -13.452,12.07016 -27.33645,24.55758 -27.33645,35.77907 v 23.51468 c 0,7.6764 -6.92702,13.91969 -15.46257,13.91969 z"
fill="#ccc"
id="path3"
style="overflow:hidden;fill:#4d4d4d;stroke-width:0.458227;stroke:#000000;stroke-opacity:1"
transform="translate(646.6554,758.05941)" /><rect
class="cls-8"
x="647.6554"
y="862.80469"
width="897.52002"
height="441.10999"
rx="11.7"
id="rect28" /></g></svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "wio-tracker-wm1110.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 91 KiB

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "rak-wismeshtap.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -176,6 +176,54 @@ enum RegionCodes: Int, CaseIterable, Identifiable {
return 100
}
}
var isCountry: Bool {
switch self {
case .unset:
return false
case .us:
return true
case .eu433:
return false
case .eu868:
return false
case .cn:
return true
case .jp:
return true
case .anz:
return false
case .kr:
return true
case .tw:
return true
case .ru:
return true
case .in:
return true
case .nz865:
return true
case .th:
return true
case .ua433:
return true
case .ua868:
return true
case .lora24:
return false
case .my433:
return true
case .my919:
return true
case .sg923:
return true
case .ph433:
return true
case .ph868:
return true
case .ph915:
return true
}
}
func protoEnumValue() -> Config.LoRaConfig.RegionCode {
switch self {

View file

@ -33,48 +33,79 @@ extension UserEntity {
let unreadMessages = messageList.filter { ($0 as AnyObject).read == false }
return unreadMessages.count
}
/// SVG Images for Vendors who are signed project backers
var hardwareImage: String? {
guard let hwModel else { return nil }
switch hwModel {
case "HELTECV1", "HELTECV3", "HELTECV20", "HELTECV21":
/// Heltec
case "HELTECHT62":
return "HELTECHT62"
case "HELTECMESHNODET114":
return "HELTECMESHNODET114"
case "HELTECV3":
return "HELTECV3"
case "HELTECVISIONMASTERE213":
return "HELTECVISIONMASTERE213"
case "HELTECVISIONMASTERE290":
return "HELTECVISIONMASTERE290"
case "HELTECWIRELESSPAPER", "HELTECWIRELESSPAPERV10":
return "HELTECWIRELESSPAPER"
case "HELTECWIRELESSTRACKER", "HELTECWIRELESSTRACKERV10":
return "HELTECWIRELESSTRACKER"
case "HELTECWSLV3":
return "HELTECWSLV3"
case "LILYGOTBEAMSCORE":
/// LilyGO
case "TDECK":
return "TDECK"
case "TECHO":
return "TECHO"
case "TWATCHS3":
return "TWATCHS3"
case "LILYGOTBEAMS3CORE":
return "LILYGOTBEAMS3CORE"
case "TBEAM", "TBEAM_V0P7":
return "TBEAM"
case "TLORAC6":
return "TLORAC6"
case "TLORAT3S3EPAPER":
return "TLORAT3S3EPAPER"
case "TLORAT3S3V1":
return "TLORAT3S3V1"
case "TLORAV2116":
return "TLORAV2116"
case "TLORAV2118":
return "TLORAV2118"
/// Seeed Studio
case "SENSECAPINDICATOR":
return "SENSECAPINDICATOR"
case "TRACKERT1000E":
return "TRACKERT1000E"
case "SEEEDXIAOS3":
return "SEEEDXIAOS3"
case "WIOWM1110":
return "WIOWM1110"
/// RAK Wireless
case "RAK4631":
return "UNSET"
case "RAK11310":
return "UNSET"
case "WISMESHTAP":
return "UNSET"
/// B&Q Consulting
case "NANOG1", "NANOG1EXPLORER":
return "NANOG1"
case "NANOG2ULTRA":
return "NANOG2ULTRA"
case "RAK4631":
return "RAK4631"
case "RAK11200":
return "RAK11200"
case "SOLAR_NODE":
return "SOLAR_NODE"
case "STATIONG1":
return "STATIONG1"
case "ТВЕАМ", "TBEAMVOP7":
return "ТВЕАМ"
case "TECHO":
return "TECHO"
case "TLORAV1", "TLORAV11P3":
return "TLORAV1"
case "TLORAV2", "TLORAT3S3", "TLORAV211P6", "TLORAV211P8":
return "TLORABOARD"
case "UNPHONE":
return "UNPHONE"
case "STATIONG2":
return "STATIONG2"
/// DIY Devices
case "RPIPICO":
return "RPIPICO"
default:
return "UNSET"
}
}
}
public func createUser(num: Int64, context: NSManagedObjectContext) -> UserEntity {
let newUser = UserEntity(context: context)
newUser.num = Int64(num)

View file

@ -61,11 +61,10 @@ extension String {
}
func camelCaseToWords() -> String {
return unicodeScalars.dropFirst().reduce(String(prefix(1))) {
return CharacterSet.uppercaseLetters.contains($1)
? $0 + " " + String($1)
: $0 + String($1)
}
return self
.replacingOccurrences(of: "([a-z])([A-Z](?=[A-Z])[a-z]*)", with: "$1 $2", options: .regularExpression)
.replacingOccurrences(of: "([A-Z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression)
.replacingOccurrences(of: "([a-z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression)
}
var length: Int {

View file

@ -27,7 +27,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
@Published var automaticallyReconnect: Bool = true
@Published var mqttProxyConnected: Bool = false
@Published var mqttError: String = ""
public var minimumVersion = "2.0.0"
public var minimumVersion = "2.3.2"
public var connectedVersion: String
public var isConnecting: Bool = false
public var isConnected: Bool = false

View file

@ -772,7 +772,8 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
}
}
} else if telemetry.metricsType == 4 {
// Update our live activity if there is one running, not available on mac iOS >= 16.2
// Update our live activity if there is one running, not available on mac
#if !targetEnvironment(macCatalyst)
#if canImport(ActivityKit)
let fifteenMinutesLater = Calendar.current.date(byAdding: .minute, value: (Int(15) ), to: Date())!
@ -801,6 +802,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
Logger.services.debug("Updated live activity.")
}
}
#endif
#endif
}
} catch {
@ -876,6 +878,9 @@ func textMessageAppPacket(
if fetchedUsers.first(where: { $0.num == packet.to }) != nil && packet.to != Constants.maximumNodeNum {
if !storeForwardBroadcast {
newMessage.toUser = fetchedUsers.first(where: { $0.num == packet.to })
} else {
/// Make a new to user if they are unknown
newMessage.toUser = createUser(num: Int64(truncatingIfNeeded: packet.to), context: context)
}
}
if fetchedUsers.first(where: { $0.num == packet.from }) != nil {
@ -903,11 +908,14 @@ func textMessageAppPacket(
newMessage.fromUser?.publicKey = packet.publicKey
}
}
if packet.rxTime > 0 {
newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
} else {
newMessage.fromUser?.userNode?.lastHeard = Date()
}
} else {
/// Make a new from user if they are unknown
newMessage.fromUser = createUser(num: Int64(truncatingIfNeeded: packet.to), context: context)
}
if packet.rxTime > 0 {
newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
} else {
newMessage.fromUser?.userNode?.lastHeard = Date()
}
newMessage.messagePayload = messageText
newMessage.messagePayloadMarkdown = generateMessageMarkdown(message: messageText!)

View file

@ -832,9 +832,9 @@ func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, s
if config.adminKey.count > 0 {
fetchedNode[0].securityConfig?.adminKey = config.adminKey[0]
if config.adminKey.count > 1 {
fetchedNode[0].securityConfig?.adminKey = config.adminKey[1]
fetchedNode[0].securityConfig?.adminKey2 = config.adminKey[1]
} else if config.adminKey.count > 2 {
fetchedNode[0].securityConfig?.adminKey = config.adminKey[2]
fetchedNode[0].securityConfig?.adminKey3 = config.adminKey[2]
}
}
fetchedNode[0].securityConfig?.isManaged = config.isManaged

View file

@ -86,7 +86,8 @@
],
"images": [
"t-echo.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 8,
@ -113,7 +114,8 @@
"images": [
"rak4631.svg",
"rak4631_case.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 10,
@ -139,7 +141,7 @@
},
{
"hwModel": 12,
"hwModelSlug": "TBEAM_S3_CORE",
"hwModelSlug": "LILYGO_TBEAM_S3_CORE",
"platformioTarget": "tbeam-s3-core",
"architecture": "esp32-s3",
"activelySupported": true,
@ -150,7 +152,8 @@
],
"images": [
"tbeam-s3-core.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 13,
@ -204,7 +207,8 @@
],
"images": [
"tlora-t3s3-v1.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 16,
@ -219,7 +223,8 @@
],
"images": [
"tlora-t3s3-epaper.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 17,
@ -243,6 +248,10 @@
"displayName": "Nano G2 Ultra",
"tags": [
"B&Q"
],
"requiresDfu": true,
"images": [
"nano-g2-ultra.svg"
]
},
{
@ -258,7 +267,8 @@
],
"images": [
"wio-tracker-wm1110.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 25,
@ -282,7 +292,11 @@
"displayName": "RAK WisBlock 11310",
"tags": [
"RAK"
]
],
"images": [
"rak11310.svg"
],
"requiresDfu": true
},
{
"hwModel": 29,
@ -294,7 +308,8 @@
"displayName": "Canary One",
"tags": [
"Canary"
]
],
"requiresDfu": true
},
{
"hwModel": 30,
@ -306,7 +321,8 @@
"displayName": "RP2040 LoRa",
"tags": [
"Waveshare"
]
],
"requiresDfu": true
},
{
"hwModel": 31,
@ -318,6 +334,10 @@
"displayName": "Station G2",
"tags": [
"B&Q"
],
"requiresDfu": true,
"images": [
"station-g2.svg"
]
},
{
@ -330,6 +350,9 @@
"displayName": "DIY V1",
"tags": [
"DIY"
],
"images": [
"diy.svg"
]
},
{
@ -407,8 +430,12 @@
"supportLevel": 3,
"displayName": "Raspberry Pi Pico",
"tags": [
"Raspberry Pi",
"RPi",
"DIY"
],
"requiresDfu": true,
"images": [
"pico.svg"
]
},
{
@ -420,8 +447,12 @@
"supportLevel": 3,
"displayName": "Raspberry Pi Pico W",
"tags": [
"Raspberry Pi",
"RPi",
"DIY"
],
"requiresDfu": true,
"images": [
"rpipicow.svg"
]
},
{
@ -437,19 +468,21 @@
],
"images": [
"heltec-wireless-tracker.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 58,
"hwModelSlug": "HELTEC_WIRELESS_TRACKER_V1_0",
"platformioTarget": "heltec-wireless-tracker-V1-0",
"architecture": "esp32-s3",
"activelySupported": true,
"activelySupported": false,
"supportLevel": 3,
"displayName": "Heltec Wireless Tracker V1.0",
"images": [
"heltec-wireless-tracker.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 49,
@ -479,7 +512,8 @@
],
"images": [
"t-deck.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 51,
@ -525,7 +559,7 @@
"hwModelSlug": "HELTEC_WIRELESS_PAPER_V1_0",
"platformioTarget": "heltec-wireless-paper-v1_0",
"architecture": "esp32-s3",
"activelySupported": true,
"activelySupported": false,
"supportLevel": 3,
"tags": [
"Heltec"
@ -542,7 +576,8 @@
"architecture": "esp32-s3",
"activelySupported": true,
"supportLevel": 3,
"displayName": "unPhone"
"displayName": "unPhone",
"requiresDfu": true
},
{
"hwModel": 48,
@ -551,7 +586,8 @@
"architecture": "esp32-s3",
"activelySupported": true,
"supportLevel": 3,
"displayName": "TrackSenger (small TFT)"
"displayName": "TrackSenger (small TFT)",
"requiresDfu": true
},
{
"hwModel": 48,
@ -560,7 +596,8 @@
"architecture": "esp32-s3",
"activelySupported": true,
"supportLevel": 3,
"displayName": "TrackSenger (big TFT)"
"displayName": "TrackSenger (big TFT)",
"requiresDfu": true
},
{
"hwModel": 48,
@ -581,7 +618,8 @@
"displayName": "EBYTE EoRa-S3",
"tags": [
"EByte"
]
],
"requiresDfu": true
},
{
"hwModel": 64,
@ -608,7 +646,8 @@
],
"images": [
"heltec-vision-master-t190.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 67,
@ -623,7 +662,8 @@
],
"images": [
"heltec-vision-master-e213.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 68,
@ -638,7 +678,8 @@
],
"images": [
"heltec-vision-master-e290.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 69,
@ -654,7 +695,8 @@
"images": [
"heltec-mesh-node-t114.svg",
"heltec-mesh-node-t114-case.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 70,
@ -684,7 +726,8 @@
],
"images": [
"tracker-t1000-e.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 72,
@ -699,6 +742,23 @@
],
"images": [
"seeed-xiao-s3.svg"
]
],
"requiresDfu": true
},
{
"hwModel": 84,
"hwModelSlug": "WISMESH_TAP",
"platformioTarget": "rak_wismeshtap",
"architecture": "nrf52840",
"activelySupported": false,
"supportLevel": 1,
"displayName": "RAK WisMesh Tap",
"tags": [
"RAK"
],
"images": [
"rak-wismeshtap.svg"
],
"requiresDfu": true
}
]

View file

@ -324,7 +324,8 @@ struct Connect: View {
}
}
}
#if canImport(ActivityKit)
#if !targetEnvironment(macCatalyst)
#if canImport(ActivityKit)
func startNodeActivity() {
liveActivityStarted = true
// 15 Minutes Local Stats Interval
@ -367,8 +368,8 @@ struct Connect: View {
}
}
}
#endif
#endif
#endif
func didDismissSheet() {
bleManager.disconnectPeripheral(reconnect: false)
}

View file

@ -41,11 +41,9 @@ struct InvalidVersion: View {
.font(.title3)
.foregroundColor(.orange)
.padding(.bottom)
Text("Version \(minimumVersion) includes breaking changes to devices and the client apps. Only nodes version \(minimumVersion) and above are supported.")
Text("Version \(minimumVersion) includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version \(minimumVersion) and above are supported.")
.font(.callout)
.padding([.leading, .trailing, .bottom])
Link("Version 1.2 End of life (EOL) Info", destination: URL(string: "https://meshtastic.org/docs/1.2-End-of-life/")!)
.font(.callout)
#if targetEnvironment(macCatalyst)
Button {

View file

@ -16,6 +16,9 @@ struct NodeDetail: View {
formatter.unitsStyle = .full
return formatter
}()
var modemPreset: ModemPresets = ModemPresets(
rawValue: UserDefaults.modemPreset
) ?? ModemPresets.longFast
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@ -44,6 +47,34 @@ struct NodeDetail: View {
NodeInfoItem(node: node)
}
Section("Node") {
HStack(alignment: .center) {
Spacer()
CircleText(
text: node.user?.shortName ?? "?",
color: Color(UIColor(hex: UInt32(node.num))),
circleSize: 75
)
if node.snr != 0 && !node.viaMqtt && node.hopsAway == 0 {
Spacer()
VStack {
let signalStrength = getLoRaSignalStrength(snr: node.snr, rssi: node.rssi, preset: modemPreset)
LoRaSignalStrengthIndicator(signalStrength: signalStrength)
Text("Signal \(signalStrength.description)").font(.footnote)
Text("SNR \(String(format: "%.2f", node.snr))dB")
.foregroundColor(getSnrColor(snr: node.snr, preset: modemPreset))
.font(.caption)
Text("RSSI \(node.rssi)dB")
.foregroundColor(getRssiColor(rssi: node.rssi))
.font(.caption)
}
}
if node.telemetries?.count ?? 0 > 0 {
Spacer()
BatteryGauge(node: node)
}
Spacer()
}
.listRowSeparator(.hidden)
if let user = node.user {
if !user.keyMatch {
Label {

View file

@ -12,61 +12,71 @@ import MapKit
struct NodeInfoItem: View {
@ObservedObject var node: NodeInfoEntity
var modemPreset: ModemPresets = ModemPresets(
rawValue: UserDefaults.modemPreset
) ?? ModemPresets.longFast
@State private var currentDevice: DeviceHardware?
var body: some View {
if let user = node.user {
ViewThatFits(in: .horizontal) {
VStack {
if let user = node.user {
HStack(alignment: .center) {
if user.hwModel != "UNSET" {
Image(user.hardwareImage ?? "UNSET")
HStack {
Spacer()
if user.hwModel != "UNSET" {
VStack(alignment: .center) {
Spacer()
Image(systemName: currentDevice?.activelySupported ?? false ? "checkmark.seal.fill" : "x.circle")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 65, height: 65)
.cornerRadius(5)
Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
.font(.callout)
} else {
Image(systemName: "person.crop.circle.badge.questionmark")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 65, height: 65)
.cornerRadius(5)
Text(String("incomplete".localized))
.aspectRatio(contentMode: .fill)
.frame(width: 75, height: 75)
.foregroundStyle(currentDevice?.activelySupported ?? false ? .green : .red)
Text( currentDevice?.activelySupported ?? false ? "Supported" : "Unsupported")
.foregroundStyle(.gray)
.font(.callout)
}
Spacer()
}
VStack(alignment: .center) {
HStack {
if user.hardwareImage != "UNSET" {
Image(user.hardwareImage ?? "UNSET")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxHeight: 150)
.cornerRadius(5)
} else {
Image(systemName: "person.crop.circle.badge.questionmark")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 75, height: 75)
.cornerRadius(5)
}
}
}
Spacer()
}
.onAppear {
Api().loadDeviceHardwareData { (hw) in
for device in hw {
let currentHardware = node.user?.hwModel ?? "UNSET"
let deviceString = device.hwModelSlug.replacingOccurrences(of: "_", with: "").uppercased()
if deviceString == currentHardware {
currentDevice = device
}
}
}
}
HStack(alignment: .center) {
Spacer()
CircleText(
text: node.user?.shortName ?? "?",
color: Color(UIColor(hex: UInt32(node.num))),
circleSize: 75
)
if node.snr != 0 && !node.viaMqtt && node.hopsAway == 0 {
Spacer()
VStack {
let signalStrength = getLoRaSignalStrength(snr: node.snr, rssi: node.rssi, preset: modemPreset)
LoRaSignalStrengthIndicator(signalStrength: signalStrength)
Text("Signal \(signalStrength.description)").font(.footnote)
Text("SNR \(String(format: "%.2f", node.snr))dB")
.foregroundColor(getSnrColor(snr: node.snr, preset: modemPreset))
.font(.caption)
Text("RSSI \(node.rssi)dB")
.foregroundColor(getRssiColor(rssi: node.rssi))
.font(.caption)
}
}
if node.telemetries?.count ?? 0 > 0 {
Spacer()
BatteryGauge(node: node)
}
Spacer()
}
.listRowSeparator(.hidden)
HStack {
Label {
Text("Model")
} icon: {
Image(systemName: "flipphone")
.symbolRenderingMode(.hierarchical)
}
Spacer()
if user.hwModel != "UNSET" {
Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
} else {
Text(String("incomplete".localized))
}
}
}

View file

@ -103,7 +103,7 @@ struct BluetoothConfig: View {
.onFirstAppear {
// Need to request a BluetoothConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty bluetooth config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -111,10 +111,12 @@ struct BluetoothConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.bluetoothConfig == nil {
Logger.mesh.info("⚙️ Empty or expired bluetooth config requesting via PKI admin")
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty bluetooth config")
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -78,7 +78,7 @@ struct DeviceConfig: View {
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $tripleClickAsAdHocPing) {
Label("Triple Click Ad Hoc Ping", systemImage: "map.pin")
Label("Triple Click Ad Hoc Ping", systemImage: "mappin")
Text("Send a position on the primary channel when the user button is triple clicked.")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
@ -229,7 +229,6 @@ struct DeviceConfig: View {
.onFirstAppear {
// Need to request a DeviceConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty device config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -237,11 +236,13 @@ struct DeviceConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.deviceConfig == nil {
Logger.mesh.info("⚙️ Empty or expired device config requesting via PKI admin")
_ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
if node.deviceConfig == nil {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty device config")
_ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -166,7 +166,6 @@ struct DisplayConfig: View {
.onFirstAppear {
// Need to request a DisplayConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty display config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -174,10 +173,12 @@ struct DisplayConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.displayConfig == nil {
Logger.mesh.info("⚙️ Empty or expired display config requesting via PKI admin")
_ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty display config")
_ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -241,7 +241,6 @@ struct LoRaConfig: View {
.onFirstAppear {
// Need to request a LoRaConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty lora config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -249,10 +248,13 @@ struct LoRaConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.loRaConfig == nil {
Logger.mesh.info("⚙️ Empty or expired lora config requesting via PKI admin")
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty lora config")
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -88,7 +88,6 @@ struct AmbientLightingConfig: View {
.onFirstAppear {
// Need to request a Ambient Lighting Config from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty ambient lighting config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -96,10 +95,12 @@ struct AmbientLightingConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.ambientLightingConfig == nil {
Logger.mesh.info("⚙️ Empty or expired ambient lighting module config requesting via PKI admin")
_ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty ambient lighting module config")
_ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -236,7 +236,6 @@ struct CannedMessagesConfig: View {
.onFirstAppear {
// Need to request a CannedMessagesModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty canned message config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -244,10 +243,12 @@ struct CannedMessagesConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.cannedMessageConfig == nil {
Logger.mesh.info("⚙️ Empty or expired canned messages module config requesting via PKI admin")
_ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty canned messages module config")
_ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -194,7 +194,6 @@ struct DetectionSensorConfig: View {
.onFirstAppear {
// Need to request a DetectionSensorModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty detection sensor config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -202,10 +201,12 @@ struct DetectionSensorConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.detectionSensorConfig == nil {
Logger.mesh.info("⚙️ Empty or expired detection sensor module config requesting via PKI admin")
_ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty detection sensor module config")
_ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -202,7 +202,6 @@ struct ExternalNotificationConfig: View {
.onFirstAppear {
// Need to request a ExternalNotificationModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty external notificaiton module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -210,10 +209,12 @@ struct ExternalNotificationConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.externalNotificationConfig == nil {
Logger.mesh.info("⚙️ Empty or expired external notificaiton module config requesting via PKI admin")
_ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty external notificaiton module config")
_ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -322,7 +322,6 @@ struct MQTTConfig: View {
.onFirstAppear {
// Need to request a MqttModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty mqtt module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -330,10 +329,12 @@ struct MQTTConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.mqttConfig == nil {
Logger.mesh.info("⚙️ Empty or expired mqtt module config requesting via PKI admin")
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty mqtt module config")
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
@ -346,8 +347,8 @@ struct MQTTConfig: View {
nearbyTopics = []
let geocoder = CLGeocoder()
if LocationsHandler.shared.locationsArray.count > 0 {
let region = RegionCodes(rawValue: Int(node?.loRaConfig?.regionCode ?? 0))?.topic
defaultTopic = "msh/" + (region ?? "UNSET")
let region = RegionCodes(rawValue: Int(node?.loRaConfig?.regionCode ?? 0))
defaultTopic = "msh/" + (region?.topic ?? "UNSET")
geocoder.reverseGeocodeLocation(LocationsHandler.shared.locationsArray.first!, completionHandler: {(placemarks, error) in
if let error {
Logger.services.error("Failed to reverse geocode location: \(error.localizedDescription)")
@ -356,8 +357,8 @@ struct MQTTConfig: View {
if let placemarks = placemarks, let placemark = placemarks.first {
let cc = locale.region?.identifier ?? "UNK"
/// Country Topic unless you are US
if placemark.isoCountryCode ?? "unknown" != cc {
/// Country Topic unless your region is a country
if !(region?.isCountry ?? false) {
let countryTopic = defaultTopic + "/" + (placemark.isoCountryCode ?? "")
if !countryTopic.isEmpty {
nearbyTopics.append(countryTopic)

View file

@ -61,7 +61,6 @@ struct PaxCounterConfig: View {
.onFirstAppear {
// Need to request a PaxCounterModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty pax counter module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -69,10 +68,12 @@ struct PaxCounterConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.paxCounterConfig == nil {
Logger.mesh.info("⚙️ Empty or expired pax counter module config requesting via PKI admin")
_ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty pax counter module config")
_ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -84,7 +84,6 @@ struct RangeTestConfig: View {
.onFirstAppear {
// Need to request a RangeTestModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty range test module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -92,10 +91,12 @@ struct RangeTestConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.rangeTestConfig == nil {
Logger.mesh.info("⚙️ Empty or expired range test module config requesting via PKI admin")
_ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty range test module config")
_ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -75,7 +75,6 @@ struct RtttlConfig: View {
.onFirstAppear {
// Need to request a RtttlConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty range test module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -83,10 +82,12 @@ struct RtttlConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.rtttlConfig == nil {
Logger.mesh.info("⚙️ Empty or expired ringtone module config requesting via PKI admin")
_ = bleManager.requestRtttlConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty ringtone module config")
_ = bleManager.requestRtttlConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -139,7 +139,6 @@ struct SerialConfig: View {
.onFirstAppear {
// Need to request a SerialModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty serial module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -147,10 +146,12 @@ struct SerialConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.serialConfig == nil {
Logger.mesh.info("⚙️ Empty or expired serial module config requesting via PKI admin")
_ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty serial module config")
_ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

View file

@ -149,7 +149,6 @@ struct StoreForwardConfig: View {
.onFirstAppear {
// Need to request a StoreForwardModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
Logger.mesh.info("empty store & forward module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@ -157,10 +156,12 @@ struct StoreForwardConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.storeForwardConfig == nil {
Logger.mesh.info("⚙️ Empty or expired store & forward module config requesting via PKI admin")
_ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
Logger.mesh.info("☠️ Using insecure legacy admin, empty store & forward module config")
_ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}

Some files were not shown because too many files have changed in this diff Show more