Remove spaces from saved RTTL value

This commit is contained in:
Garth Vander Houwen 2024-01-19 10:56:57 -08:00
parent 2c76631681
commit cff96bd37c
8 changed files with 238 additions and 2 deletions

View file

@ -107,6 +107,7 @@
DDAB580F2B0DAFBC00147258 /* LocationEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAB580E2B0DAFBC00147258 /* LocationEntityExtension.swift */; };
DDAD49ED2AFB39DC00B4425D /* MeshMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAD49EC2AFB39DC00B4425D /* MeshMap.swift */; };
DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5226EB1DF10058C060 /* BLEManager.swift */; };
DDB233CF2B5A140B00DA6FB1 /* CarPlaySceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB233CE2B5A140B00DA6FB1 /* CarPlaySceneDelegate.swift */; };
DDB6ABD628AE742000384BA1 /* BluetoothConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABD528AE742000384BA1 /* BluetoothConfig.swift */; };
DDB6ABD928B0A4BA00384BA1 /* BluetoothModes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABD828B0A4BA00384BA1 /* BluetoothModes.swift */; };
DDB6ABDB28B0AC6000384BA1 /* DistanceText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */; };
@ -334,6 +335,7 @@
DDAB580E2B0DAFBC00147258 /* LocationEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationEntityExtension.swift; sourceTree = "<group>"; };
DDAD49EC2AFB39DC00B4425D /* MeshMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshMap.swift; sourceTree = "<group>"; };
DDAF8C5226EB1DF10058C060 /* BLEManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BLEManager.swift; sourceTree = "<group>"; };
DDB233CE2B5A140B00DA6FB1 /* CarPlaySceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarPlaySceneDelegate.swift; sourceTree = "<group>"; };
DDB6ABD528AE742000384BA1 /* BluetoothConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothConfig.swift; sourceTree = "<group>"; };
DDB6ABD828B0A4BA00384BA1 /* BluetoothModes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothModes.swift; sourceTree = "<group>"; };
DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DistanceText.swift; sourceTree = "<group>"; };
@ -698,6 +700,14 @@
path = Protobufs;
sourceTree = "<group>";
};
DDB233CD2B5A13C600DA6FB1 /* CarPlay */ = {
isa = PBXGroup;
children = (
DDB233CE2B5A140B00DA6FB1 /* CarPlaySceneDelegate.swift */,
);
path = CarPlay;
sourceTree = "<group>";
};
DDB75A122A0593CD006ED576 /* Map */ = {
isa = PBXGroup;
children = (
@ -736,6 +746,7 @@
DDC2E15626CE248E0042C5E4 /* Meshtastic */ = {
isa = PBXGroup;
children = (
DDB233CD2B5A13C600DA6FB1 /* CarPlay */,
DD7709392AA1ABA1007A8BF0 /* Tips */,
DD90860A26F645B700DC5189 /* Meshtastic.entitlements */,
DD8ED9C6289CE4A100B3B0AB /* Enums */,
@ -1171,6 +1182,7 @@
DD5E5208298EE33B00D21B61 /* rtttl.pb.swift in Sources */,
DD6193792863875F00E59241 /* SerialConfig.swift in Sources */,
DDDB263F2AABEE20003AFCB7 /* NodeList.swift in Sources */,
DDB233CF2B5A140B00DA6FB1 /* CarPlaySceneDelegate.swift in Sources */,
DDA0B6B2294CDC55001356EC /* Channels.swift in Sources */,
DDE9659C2B1C3B6A00531070 /* RouteRecorder.swift in Sources */,
DDB8F4102A9EE5B400230ECE /* Messages.swift in Sources */,

View file

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "RoundIcon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "RoundIcon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

View file

@ -0,0 +1,182 @@
//
// CarPlaySceneDelegate.swift
// Meshtastic
//
// Created by Garth Vander Houwen on 1/18/24.
//
import Foundation
import CarPlay
@objc class CarPlaySceneDelegate: NSObject, CPTemplateApplicationSceneDelegate {
private var interfaceController: CPInterfaceController?
private var savedTabBarTemplate: CPTabBarTemplate?
// https://developer.apple.com/documentation/carplay/displaying_content_in_carplay
// CarPlay calls this function to initialize the scene.
func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) {
// Save the interface controller
self.interfaceController = interfaceController
let template = tabBarTemplate()
self.savedTabBarTemplate = template
// Create the root template (screen) and install it at the root of the navigation hierarchy.
interfaceController.setRootTemplate(template, animated: true, completion: nil)
}
func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didDisconnectInterfaceController interfaceController: CPInterfaceController) {
self.interfaceController = nil
}
private func tabBarTemplate() -> CPTabBarTemplate {
return CPTabBarTemplate(templates: [
channelListTemplate(),
listTemplate(),
// gridTemplate(),
// informationTemplate(layout: .leading)
])
}
private func replaceTabs() {
self.savedTabBarTemplate?.updateTemplates([
channelListTemplate(),
listTemplate(),
gridTemplate(),
informationTemplate(layout: .leading),
informationTemplate(layout: .leading),
])
}
private func channelListTemplate() -> CPListTemplate {
let template = CPListTemplate(
title: "Channels",
sections: [
CPListSection(items: [
listItem(),
listItem(),
], header: nil, sectionIndexTitle: nil),
]
)
template.tabTitle = "Channels"
template.tabImage = UIImage(systemName: "fibrechannel")// UIImage(named: "RoundIcon")!
return template
}
private func listTemplate() -> CPListTemplate {
let template = CPListTemplate(
title: "Direct Messages",
sections: [
CPListSection(items: [
listItem(),
listItem(),
], header: nil, sectionIndexTitle: nil),
]
)
template.tabTitle = "Nodes"
template.tabImage = UIImage(systemName: "message.fill")// UIImage(named: "RoundIcon")!
return template
}
private func listItem() -> CPListTemplateItem {
let item = CPListItem(text: "Text", detailText: "Detail Text", image: UIImage(named: "RoundIcon")!, accessoryImage: nil, accessoryType: .none)
item.handler = { [weak self] (item, completion) in
guard let self = self else {
completion()
return
}
self.interfaceController?.pushTemplate(
self.listTemplate(),
animated: true,
completion: { (didPresent, error) in
completion()
}
)
}
return item
}
private func gridTemplate() -> CPGridTemplate {
let template = CPGridTemplate(
title: "Grid Title",
gridButtons: [
gridButton(),
gridButton(),
gridButton(),
gridButton(),
gridButton(),
gridButton(),
]
)
template.tabTitle = "Grid"
template.tabImage = UIImage(named: "RoundIcon")!
return template
}
private func gridButton() -> CPGridButton {
return CPGridButton(
titleVariants: [
"Maybe a bit much too long of a title",
"Medium Title",
"Title"
],
image: UIImage(named: "RoundIcon")!,
handler: { [weak self] button in
guard let self = self else { return }
self.interfaceController?.pushTemplate(
self.gridTemplate(),
animated: true,
completion: nil
)
}
)
}
private func informationTemplate(layout: CPInformationTemplateLayout) -> CPInformationTemplate {
let template = CPInformationTemplate(
title: "Information Title",
layout: layout,
items: [
CPInformationItem(title: "Item\nTitle\nThird\nFourth", detail: "Item\nDetail\nThird line\nFourth line"),
CPInformationItem(title: "Item Title", detail: nil),
CPInformationItem(title: "Item Title", detail: "Item Detail"),
CPInformationItem(title: "Item Title", detail: nil),
CPInformationItem(title: "Item Title Item Title Item Title Item Title Item Title", detail: "Item Detail Item Detail Item Detail Item Detail Item Detail "),
CPInformationItem(title: "Item Title", detail: nil),
],
actions: [
textButton(style: .confirm),
textButton(style: .normal),
// textButton(style: .cancel),
]
)
template.tabTitle = "Information"
template.tabImage = UIImage(named: "RoundIcon")!
return template
}
private func textButton(style: CPTextButtonStyle) -> CPTextButton{
return CPTextButton(
title: "Text Button",
textStyle: style,
handler: { [weak self] button in
guard let self = self else { return }
self.interfaceController?.pushTemplate(
self.informationTemplate(layout: .twoColumn),
animated: true,
completion: nil
)
// self.replaceTabs()
}
)
}
}

View file

@ -33,6 +33,10 @@
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>INIntentsSupported</key>
<array>
<string>Intent</string>
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
@ -66,7 +70,21 @@
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>CPTemplateApplicationScene</string>
<key>UISceneDelegateClassName</key>
<string>$(SWIFT_MODULE_NAME).CarPlaySceneDelegate</string>
<key>UISceneConfigurationName</key>
<string>CarPlay scene</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>

View file

@ -18,5 +18,7 @@
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>com.apple.developer.carplay-communication</key>
<true/>
</dict>
</plist>

View file

@ -96,7 +96,7 @@ struct RtttlConfig: View {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
if connectedNode != nil {
let adminMessageId = bleManager.saveRtttlConfig(ringtone: ringtone, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.saveRtttlConfig(ringtone: ringtone.trimmingCharacters(in: .whitespacesAndNewlines), fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save