mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 23:45:20 +00:00
Merge pull request #295 from permissionlesstech/network-notifications
Add network availability notifications
This commit is contained in:
@@ -193,18 +193,18 @@
|
|||||||
3FA8FF26ABDC1C642A8C7AE5 /* BitchatMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitchatMessageTests.swift; sourceTree = "<group>"; };
|
3FA8FF26ABDC1C642A8C7AE5 /* BitchatMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitchatMessageTests.swift; sourceTree = "<group>"; };
|
||||||
527EB217EFDFAD4CF1C91F07 /* bitchat.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = bitchat.entitlements; sourceTree = "<group>"; };
|
527EB217EFDFAD4CF1C91F07 /* bitchat.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = bitchat.entitlements; sourceTree = "<group>"; };
|
||||||
53D535D9CE0B875F47402290 /* BinaryProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocolTests.swift; sourceTree = "<group>"; };
|
53D535D9CE0B875F47402290 /* BinaryProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocolTests.swift; sourceTree = "<group>"; };
|
||||||
61F92EBA29C47C0FCC482F1F /* bitchatShareExtension.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.extensionkit-extension"; path = bitchatShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
61F92EBA29C47C0FCC482F1F /* bitchatShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = bitchatShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6E2446380E7A44E49A35B664 /* IdentityModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityModels.swift; sourceTree = "<group>"; };
|
6E2446380E7A44E49A35B664 /* IdentityModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityModels.swift; sourceTree = "<group>"; };
|
||||||
763E0DBA9492A654FC0CDCB9 /* AppInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfoView.swift; sourceTree = "<group>"; };
|
763E0DBA9492A654FC0CDCB9 /* AppInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfoView.swift; sourceTree = "<group>"; };
|
||||||
8DE9CDF66D4E52D268851048 /* MessagePaddingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePaddingTests.swift; sourceTree = "<group>"; };
|
8DE9CDF66D4E52D268851048 /* MessagePaddingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePaddingTests.swift; sourceTree = "<group>"; };
|
||||||
8F3A7C058C2C8E1A06C8CF8B /* bitchat_macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = bitchat_macOS.app; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
8F3A7C058C2C8E1A06C8CF8B /* bitchat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
95F16C3A4A5621C74461D8D3 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
95F16C3A4A5621C74461D8D3 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
96D0D41CA19EE5A772AA8434 /* bitchat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
96D0D41CA19EE5A772AA8434 /* bitchat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
9AC141774F6671FCDC347DC7 /* LinkPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewView.swift; sourceTree = "<group>"; };
|
9AC141774F6671FCDC347DC7 /* LinkPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewView.swift; sourceTree = "<group>"; };
|
||||||
A08E03AA0C63E97C91749AEC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
A08E03AA0C63E97C91749AEC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
A2136C3E22D02D4A8DBE7EAB /* BinaryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocol.swift; sourceTree = "<group>"; };
|
A2136C3E22D02D4A8DBE7EAB /* BinaryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocol.swift; sourceTree = "<group>"; };
|
||||||
AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRetryService.swift; sourceTree = "<group>"; };
|
AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRetryService.swift; sourceTree = "<group>"; };
|
||||||
C0DB1DE27F0AAB5092663E8E /* bitchatTests_iOS.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = bitchatTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
C0DB1DE27F0AAB5092663E8E /* bitchatTests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = bitchatTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C1B378C16594575FCC7F9C75 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
C1B378C16594575FCC7F9C75 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||||
CB043CA5EEB9AC8B07D61E97 /* OptimizedBloomFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizedBloomFilter.swift; sourceTree = "<group>"; };
|
CB043CA5EEB9AC8B07D61E97 /* OptimizedBloomFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizedBloomFilter.swift; sourceTree = "<group>"; };
|
||||||
D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothMeshService.swift; sourceTree = "<group>"; };
|
D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothMeshService.swift; sourceTree = "<group>"; };
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
96D0D41CA19EE5A772AA8434 /* bitchat.app */,
|
96D0D41CA19EE5A772AA8434 /* bitchat.app */,
|
||||||
8F3A7C058C2C8E1A06C8CF8B /* bitchat_macOS.app */,
|
8F3A7C058C2C8E1A06C8CF8B /* bitchat.app */,
|
||||||
61F92EBA29C47C0FCC482F1F /* bitchatShareExtension.appex */,
|
61F92EBA29C47C0FCC482F1F /* bitchatShareExtension.appex */,
|
||||||
C0DB1DE27F0AAB5092663E8E /* bitchatTests_iOS.xctest */,
|
C0DB1DE27F0AAB5092663E8E /* bitchatTests_iOS.xctest */,
|
||||||
03C57F452B55FD0FD8F51421 /* bitchatTests_macOS.xctest */,
|
03C57F452B55FD0FD8F51421 /* bitchatTests_macOS.xctest */,
|
||||||
@@ -392,7 +392,7 @@
|
|||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
);
|
);
|
||||||
productName = bitchat_macOS;
|
productName = bitchat_macOS;
|
||||||
productReference = 8F3A7C058C2C8E1A06C8CF8B /* bitchat_macOS.app */;
|
productReference = 8F3A7C058C2C8E1A06C8CF8B /* bitchat.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
47FF23248747DD7CB666CB91 /* bitchatTests_macOS */ = {
|
47FF23248747DD7CB666CB91 /* bitchatTests_macOS */ = {
|
||||||
@@ -475,7 +475,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
LastUpgradeCheck = 1430;
|
LastUpgradeCheck = 1640;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
0576A29205865664C0937536 = {
|
0576A29205865664C0937536 = {
|
||||||
DevelopmentTeam = L3N5LHJD5Y;
|
DevelopmentTeam = L3N5LHJD5Y;
|
||||||
@@ -704,7 +704,6 @@
|
|||||||
CODE_SIGNING_ALLOWED = YES;
|
CODE_SIGNING_ALLOWED = YES;
|
||||||
CODE_SIGNING_REQUIRED = YES;
|
CODE_SIGNING_REQUIRED = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
|
||||||
INFOPLIST_FILE = bitchatTests/Info.plist;
|
INFOPLIST_FILE = bitchatTests/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@@ -727,7 +726,6 @@
|
|||||||
CODE_SIGNING_ALLOWED = YES;
|
CODE_SIGNING_ALLOWED = YES;
|
||||||
CODE_SIGNING_REQUIRED = YES;
|
CODE_SIGNING_REQUIRED = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
|
||||||
INFOPLIST_FILE = bitchatTests/Info.plist;
|
INFOPLIST_FILE = bitchatTests/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@@ -751,7 +749,7 @@
|
|||||||
CODE_SIGNING_REQUIRED = YES;
|
CODE_SIGNING_REQUIRED = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
INFOPLIST_FILE = bitchatTests/Info.plist;
|
INFOPLIST_FILE = bitchatTests/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -774,7 +772,6 @@
|
|||||||
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
|
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = bitchatShareExtension/bitchatShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = bitchatShareExtension/bitchatShareExtension.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
|
||||||
INFOPLIST_FILE = bitchatShareExtension/Info.plist;
|
INFOPLIST_FILE = bitchatShareExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@@ -799,7 +796,6 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = bitchat/bitchat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = bitchat/bitchat.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = bitchat/Info.plist;
|
INFOPLIST_FILE = bitchat/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
|
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
|
||||||
@@ -829,7 +825,7 @@
|
|||||||
CODE_SIGNING_REQUIRED = YES;
|
CODE_SIGNING_REQUIRED = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
INFOPLIST_FILE = bitchatTests/Info.plist;
|
INFOPLIST_FILE = bitchatTests/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -854,7 +850,6 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = bitchat/bitchat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = bitchat/bitchat.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = bitchat/Info.plist;
|
INFOPLIST_FILE = bitchat/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
|
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
|
||||||
@@ -886,7 +881,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = "bitchat/bitchat-macOS.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "bitchat/bitchat-macOS.entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = bitchat/Info.plist;
|
INFOPLIST_FILE = bitchat/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@@ -896,6 +891,7 @@
|
|||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
|
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
|
||||||
PRODUCT_NAME = bitchat;
|
PRODUCT_NAME = bitchat;
|
||||||
|
REGISTER_APP_GROUPS = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
@@ -936,9 +932,12 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
@@ -969,7 +968,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = "bitchat/bitchat-macOS.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "bitchat/bitchat-macOS.entitlements";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = bitchat/Info.plist;
|
INFOPLIST_FILE = bitchat/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@@ -979,6 +978,7 @@
|
|||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
|
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
|
||||||
PRODUCT_NAME = bitchat;
|
PRODUCT_NAME = bitchat;
|
||||||
|
REGISTER_APP_GROUPS = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
@@ -1019,9 +1019,12 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
@@ -1057,7 +1060,6 @@
|
|||||||
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
|
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = bitchatShareExtension/bitchatShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = bitchatShareExtension/bitchatShareExtension.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
|
||||||
INFOPLIST_FILE = bitchatShareExtension/Info.plist;
|
INFOPLIST_FILE = bitchatShareExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
|||||||
@@ -35,6 +35,12 @@
|
|||||||
<string>bitchat uses Bluetooth to create a secure mesh network for chatting with nearby users.</string>
|
<string>bitchat uses Bluetooth to create a secure mesh network for chatting with nearby users.</string>
|
||||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||||
<string>bitchat uses Bluetooth to discover and connect with other bitchat users nearby.</string>
|
<string>bitchat uses Bluetooth to discover and connect with other bitchat users nearby.</string>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>bluetooth-central</string>
|
||||||
|
<string>bluetooth-peripheral</string>
|
||||||
|
<string>remote-notification</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ class BluetoothMeshService: NSObject {
|
|||||||
private let maxTTL: UInt8 = 7 // Maximum hops for long-distance delivery
|
private let maxTTL: UInt8 = 7 // Maximum hops for long-distance delivery
|
||||||
private var announcedToPeers = Set<String>() // Track which peers we've announced to
|
private var announcedToPeers = Set<String>() // Track which peers we've announced to
|
||||||
private var announcedPeers = Set<String>() // Track peers who have already been announced
|
private var announcedPeers = Set<String>() // Track peers who have already been announced
|
||||||
|
private var hasNotifiedNetworkAvailable = false // Track if we've notified about network availability
|
||||||
|
private var lastNetworkNotificationTime: Date? // Track when we last sent a network notification
|
||||||
|
private var networkBecameEmptyTime: Date? // Track when the network became empty
|
||||||
|
private let networkNotificationCooldown: TimeInterval = 300 // 5 minutes between notifications
|
||||||
|
private let networkEmptyResetDelay: TimeInterval = 60 // 1 minute before resetting notification flag
|
||||||
private var intentionalDisconnects = Set<String>() // Track peripherals we're disconnecting intentionally
|
private var intentionalDisconnects = Set<String>() // Track peripherals we're disconnecting intentionally
|
||||||
private var peerLastSeenTimestamps = LRUCache<String, Date>(maxSize: 100) // Bounded cache for peer timestamps
|
private var peerLastSeenTimestamps = LRUCache<String, Date>(maxSize: 100) // Bounded cache for peer timestamps
|
||||||
private var cleanupTimer: Timer? // Timer to clean up stale peers
|
private var cleanupTimer: Timer? // Timer to clean up stale peers
|
||||||
@@ -599,6 +604,8 @@ class BluetoothMeshService: NSObject {
|
|||||||
activePeers.removeAll()
|
activePeers.removeAll()
|
||||||
}
|
}
|
||||||
announcedPeers.removeAll()
|
announcedPeers.removeAll()
|
||||||
|
// For normal disconnect, respect the timing
|
||||||
|
networkBecameEmptyTime = Date()
|
||||||
|
|
||||||
// Clear announcement tracking
|
// Clear announcement tracking
|
||||||
announcedToPeers.removeAll()
|
announcedToPeers.removeAll()
|
||||||
@@ -1231,6 +1238,10 @@ class BluetoothMeshService: NSObject {
|
|||||||
peripheralRSSI.removeAll()
|
peripheralRSSI.removeAll()
|
||||||
announcedToPeers.removeAll()
|
announcedToPeers.removeAll()
|
||||||
announcedPeers.removeAll()
|
announcedPeers.removeAll()
|
||||||
|
// For emergency/panic, reset immediately
|
||||||
|
hasNotifiedNetworkAvailable = false
|
||||||
|
networkBecameEmptyTime = nil
|
||||||
|
lastNetworkNotificationTime = nil
|
||||||
processedMessages.removeAll()
|
processedMessages.removeAll()
|
||||||
incomingFragments.removeAll()
|
incomingFragments.removeAll()
|
||||||
fragmentMetadata.removeAll()
|
fragmentMetadata.removeAll()
|
||||||
@@ -1331,6 +1342,29 @@ class BluetoothMeshService: NSObject {
|
|||||||
|
|
||||||
if !peersToRemove.isEmpty {
|
if !peersToRemove.isEmpty {
|
||||||
notifyPeerListUpdate()
|
notifyPeerListUpdate()
|
||||||
|
|
||||||
|
// Mark when network became empty, but don't reset flag immediately
|
||||||
|
let currentNetworkSize = collectionsQueue.sync { activePeers.count }
|
||||||
|
if currentNetworkSize == 0 && networkBecameEmptyTime == nil {
|
||||||
|
networkBecameEmptyTime = Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we should reset the notification flag
|
||||||
|
if let emptyTime = networkBecameEmptyTime {
|
||||||
|
let currentNetworkSize = collectionsQueue.sync { activePeers.count }
|
||||||
|
if currentNetworkSize == 0 {
|
||||||
|
// Network is still empty, check if enough time has passed
|
||||||
|
let timeSinceEmpty = Date().timeIntervalSince(emptyTime)
|
||||||
|
if timeSinceEmpty >= networkEmptyResetDelay {
|
||||||
|
// Reset the flag after network has been empty for the delay period
|
||||||
|
hasNotifiedNetworkAvailable = false
|
||||||
|
// Keep the empty time set so we don't immediately notify again
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Network is no longer empty, clear the empty time
|
||||||
|
networkBecameEmptyTime = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2079,6 +2113,33 @@ class BluetoothMeshService: NSObject {
|
|||||||
}
|
}
|
||||||
self.notifyPeerListUpdate(immediate: true)
|
self.notifyPeerListUpdate(immediate: true)
|
||||||
|
|
||||||
|
// Send network available notification if appropriate
|
||||||
|
let currentNetworkSize = collectionsQueue.sync { self.activePeers.count }
|
||||||
|
if currentNetworkSize > 0 {
|
||||||
|
// Clear empty time since network is active
|
||||||
|
networkBecameEmptyTime = nil
|
||||||
|
|
||||||
|
if !hasNotifiedNetworkAvailable {
|
||||||
|
// Check if enough time has passed since last notification
|
||||||
|
let now = Date()
|
||||||
|
var shouldSendNotification = true
|
||||||
|
|
||||||
|
if let lastNotification = lastNetworkNotificationTime {
|
||||||
|
let timeSinceLastNotification = now.timeIntervalSince(lastNotification)
|
||||||
|
if timeSinceLastNotification < networkNotificationCooldown {
|
||||||
|
// Too soon to send another notification
|
||||||
|
shouldSendNotification = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if shouldSendNotification {
|
||||||
|
hasNotifiedNetworkAvailable = true
|
||||||
|
lastNetworkNotificationTime = now
|
||||||
|
NotificationService.shared.sendNetworkAvailableNotification(peerCount: currentNetworkSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
// Check if this is a favorite peer and send notification
|
// Check if this is a favorite peer and send notification
|
||||||
// Note: This might not work immediately if key exchange hasn't happened yet
|
// Note: This might not work immediately if key exchange hasn't happened yet
|
||||||
@@ -2928,6 +2989,12 @@ extension BluetoothMeshService: CBCentralManagerDelegate {
|
|||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.delegate?.didDisconnectFromPeer(peerID)
|
self.delegate?.didDisconnectFromPeer(peerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark when network became empty, but don't reset flag immediately
|
||||||
|
let currentNetworkSize = collectionsQueue.sync { activePeers.count }
|
||||||
|
if currentNetworkSize == 0 && networkBecameEmptyTime == nil {
|
||||||
|
networkBecameEmptyTime = Date()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.notifyPeerListUpdate()
|
self.notifyPeerListUpdate()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,43 +20,33 @@ class NotificationService {
|
|||||||
private init() {}
|
private init() {}
|
||||||
|
|
||||||
func requestAuthorization() {
|
func requestAuthorization() {
|
||||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
|
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
|
||||||
if granted {
|
if granted {
|
||||||
// Permission granted
|
// Permission granted
|
||||||
|
} else {
|
||||||
|
// Permission denied
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendLocalNotification(title: String, body: String, identifier: String) {
|
func sendLocalNotification(title: String, body: String, identifier: String) {
|
||||||
// Check if app is in foreground
|
// For now, skip app state check entirely to avoid thread issues
|
||||||
#if os(iOS)
|
// The NotificationDelegate will handle foreground presentation
|
||||||
guard UIApplication.shared.applicationState != .active else {
|
DispatchQueue.main.async {
|
||||||
// App is active/foreground, skipping notification
|
let content = UNMutableNotificationContent()
|
||||||
return
|
content.title = title
|
||||||
}
|
content.body = body
|
||||||
// App state checked, sending notification
|
content.sound = .default
|
||||||
#elseif os(macOS)
|
|
||||||
// On macOS, check if app is active
|
|
||||||
guard !NSApplication.shared.isActive else {
|
|
||||||
// App is active/foreground, skipping notification
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// App is not active, sending notification
|
|
||||||
#endif
|
|
||||||
|
|
||||||
let content = UNMutableNotificationContent()
|
let request = UNNotificationRequest(
|
||||||
content.title = title
|
identifier: identifier,
|
||||||
content.body = body
|
content: content,
|
||||||
content.sound = .default
|
trigger: nil // Deliver immediately
|
||||||
|
)
|
||||||
|
|
||||||
let request = UNNotificationRequest(
|
UNUserNotificationCenter.current().add(request) { _ in
|
||||||
identifier: identifier,
|
// Notification added
|
||||||
content: content,
|
}
|
||||||
trigger: nil // Deliver immediately
|
|
||||||
)
|
|
||||||
|
|
||||||
UNUserNotificationCenter.current().add(request) { _ in
|
|
||||||
// Notification added
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,10 +67,48 @@ class NotificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sendFavoriteOnlineNotification(nickname: String) {
|
func sendFavoriteOnlineNotification(nickname: String) {
|
||||||
let title = "⭐ \(nickname) is online"
|
// Send directly without checking app state for favorites
|
||||||
let body = "wanna get in there?"
|
DispatchQueue.main.async {
|
||||||
let identifier = "favorite-online-\(UUID().uuidString)"
|
let content = UNMutableNotificationContent()
|
||||||
|
content.title = "⭐ \(nickname) is online!"
|
||||||
|
content.body = "wanna get in there?"
|
||||||
|
content.sound = .default
|
||||||
|
|
||||||
sendLocalNotification(title: title, body: body, identifier: identifier)
|
let request = UNNotificationRequest(
|
||||||
|
identifier: "favorite-online-\(UUID().uuidString)",
|
||||||
|
content: content,
|
||||||
|
trigger: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
UNUserNotificationCenter.current().add(request) { _ in
|
||||||
|
// Notification added
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendNetworkAvailableNotification(peerCount: Int) {
|
||||||
|
let title = "👥 bitchatters nearby!"
|
||||||
|
let body = peerCount == 1 ? "1 person around" : "\(peerCount) people around"
|
||||||
|
let identifier = "network-available-\(Date().timeIntervalSince1970)"
|
||||||
|
|
||||||
|
// For network notifications, we want to show them even in foreground
|
||||||
|
// No app state check - let the notification delegate handle presentation
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let content = UNMutableNotificationContent()
|
||||||
|
content.title = title
|
||||||
|
content.body = body
|
||||||
|
content.sound = .default
|
||||||
|
content.interruptionLevel = .timeSensitive // Make it more prominent
|
||||||
|
|
||||||
|
let request = UNNotificationRequest(
|
||||||
|
identifier: identifier,
|
||||||
|
content: content,
|
||||||
|
trigger: nil // Deliver immediately
|
||||||
|
)
|
||||||
|
|
||||||
|
UNUserNotificationCenter.current().add(request) { _ in
|
||||||
|
// Notification added
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ struct AppInfoView: View {
|
|||||||
|
|
||||||
// MARK: - Constants
|
// MARK: - Constants
|
||||||
private enum Strings {
|
private enum Strings {
|
||||||
static let appName = "bitchat"
|
static let appName = "bitchat/"
|
||||||
static let tagline = "mesh sidegroupchat"
|
static let tagline = "mesh sidegroupchat"
|
||||||
|
|
||||||
enum Features {
|
enum Features {
|
||||||
|
|||||||
Reference in New Issue
Block a user