Add retry for failed media packets

This commit is contained in:
Janez T
2026-03-02 08:04:16 +01:00
parent 790c205541
commit e13143aead
5 changed files with 41 additions and 29 deletions

View File

@@ -489,7 +489,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 64; CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = JND55328G8; DEVELOPMENT_TEAM = JND55328G8;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -511,7 +511,7 @@
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 64; CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = JND55328G8; DEVELOPMENT_TEAM = JND55328G8;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
@@ -530,7 +530,7 @@
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 64; CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = JND55328G8; DEVELOPMENT_TEAM = JND55328G8;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
@@ -547,7 +547,7 @@
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 64; CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = JND55328G8; DEVELOPMENT_TEAM = JND55328G8;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
@@ -679,7 +679,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 64; CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = JND55328G8; DEVELOPMENT_TEAM = JND55328G8;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -702,7 +702,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 64; CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = JND55328G8; DEVELOPMENT_TEAM = JND55328G8;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;

View File

@@ -43,7 +43,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>64</string> <string>65</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSBluetoothAlwaysUsageDescription</key> <key>NSBluetoothAlwaysUsageDescription</key>

View File

@@ -5,19 +5,22 @@
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000612"> <testcase classname="fastlane.lanes" name="0: default_platform" time="0.000539">
</testcase> </testcase>
<testcase classname="fastlane.lanes" name="1: increment_build_number" time="0.806854"> <testcase classname="fastlane.lanes" name="1: increment_build_number" time="0.431898">
</testcase> </testcase>
<testcase classname="fastlane.lanes" name="2: build_app" time="42.370043"> <testcase classname="fastlane.lanes" name="2: build_app" time="128.573196">
<failure message="/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/actions/actions_helper.rb:67:in &apos;Fastlane::Actions.execute_action&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:255:in &apos;block in Fastlane::Runner#execute_action&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:229:in &apos;Dir.chdir&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:229:in &apos;Fastlane::Runner#execute_action&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:157:in &apos;Fastlane::Runner#trigger_action_by_name&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/fast_file.rb:159:in &apos;Fastlane::FastFile#method_missing&apos;&#10;Fastfile:22:in &apos;block (2 levels) in Fastlane::FastFile#parsing_binding&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/lane.rb:41:in &apos;Fastlane::Lane#call&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:49:in &apos;block in Fastlane::Runner#execute&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:45:in &apos;Dir.chdir&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/runner.rb:45:in &apos;Fastlane::Runner#execute&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/lane_manager.rb:46:in &apos;Fastlane::LaneManager.cruise_lane&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/command_line_handler.rb:34:in &apos;Fastlane::CommandLineHandler.handle&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/commands_generator.rb:110:in &apos;block (2 levels) in Fastlane::CommandsGenerator#run&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in &apos;Commander::Command#call&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in &apos;Commander::Command#run&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in &apos;Commander::Runner#run_active_command&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in &apos;Commander::Runner#run!&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in &apos;Commander::Delegates#run!&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/commands_generator.rb:363:in &apos;Fastlane::CommandsGenerator#run&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/commands_generator.rb:43:in &apos;Fastlane::CommandsGenerator.start&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/fastlane/lib/fastlane/cli_tools_distributor.rb:132:in &apos;Fastlane::CLIToolsDistributor.take_off&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/gems/fastlane-2.231.1/bin/fastlane:23:in &apos;&lt;top (required)&gt;&apos;&#10;/opt/homebrew/Cellar/ruby/4.0.1/lib/ruby/4.0.0/rubygems.rb:303:in &apos;Kernel#load&apos;&#10;/opt/homebrew/Cellar/ruby/4.0.1/lib/ruby/4.0.0/rubygems.rb:303:in &apos;Gem.activate_and_load_bin_path&apos;&#10;/opt/homebrew/Cellar/fastlane/2.231.1/libexec/bin/fastlane:25:in &apos;&lt;main&gt;&apos;&#10;&#10;Error building the application - see the log above" /> </testcase>
<testcase classname="fastlane.lanes" name="3: upload_to_app_store" time="64710.01441">
</testcase> </testcase>

View File

@@ -457,6 +457,7 @@ class _MessagesTabState extends State<MessagesTab> {
grayscale: grayscale, grayscale: grayscale,
); );
if (result == null) { if (result == null) {
if (!mounted) return;
ToastLogger.error(context, 'Image compression failed'); ToastLogger.error(context, 'Image compression failed');
return; return;
} }
@@ -487,6 +488,7 @@ class _MessagesTabState extends State<MessagesTab> {
); );
if (fragments.isEmpty) { if (fragments.isEmpty) {
if (!mounted) return;
ToastLogger.error(context, 'Image fragmentation failed'); ToastLogger.error(context, 'Image fragmentation failed');
return; return;
} }
@@ -494,6 +496,7 @@ class _MessagesTabState extends State<MessagesTab> {
// Build envelope. // Build envelope.
final deviceKey = connectionProvider.deviceInfo.publicKey; final deviceKey = connectionProvider.deviceInfo.publicKey;
if (deviceKey == null || deviceKey.length < 6) { if (deviceKey == null || deviceKey.length < 6) {
if (!mounted) return;
ToastLogger.error(context, 'Device key unavailable'); ToastLogger.error(context, 'Device key unavailable');
return; return;
} }
@@ -513,6 +516,8 @@ class _MessagesTabState extends State<MessagesTab> {
timestampSec: DateTime.now().millisecondsSinceEpoch ~/ 1000, timestampSec: DateTime.now().millisecondsSinceEpoch ~/ 1000,
); );
if (!mounted) return;
// Cache for deferred serving. // Cache for deferred serving.
final imageProvider = context.read<ip.ImageProvider>(); final imageProvider = context.read<ip.ImageProvider>();
imageProvider.cacheOutgoingSession(sessionId, fragments, envelope); imageProvider.cacheOutgoingSession(sessionId, fragments, envelope);
@@ -555,6 +560,7 @@ class _MessagesTabState extends State<MessagesTab> {
); );
if (!sent) { if (!sent) {
messagesProvider.markMessageFailed(msgId); messagesProvider.markMessageFailed(msgId);
if (!mounted) return;
ToastLogger.error(context, 'Failed to announce image'); ToastLogger.error(context, 'Failed to announce image');
} }
} }
@@ -566,6 +572,7 @@ class _MessagesTabState extends State<MessagesTab> {
); );
} catch (e, st) { } catch (e, st) {
debugPrint('❌ [Image] _pickAndSendImage: $e\n$st'); debugPrint('❌ [Image] _pickAndSendImage: $e\n$st');
if (!mounted) return;
ToastLogger.error(context, 'Image send failed'); ToastLogger.error(context, 'Image send failed');
} finally { } finally {
if (mounted) setState(() => _isSendingImage = false); if (mounted) setState(() => _isSendingImage = false);

View File

@@ -1206,24 +1206,26 @@ class _SettingsScreenState extends State<SettingsScreen> {
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
title: const Text('Max image size'), title: const Text('Max image size'),
content: SingleChildScrollView( content: SingleChildScrollView(
child: Column( child: RadioGroup<int>(
mainAxisSize: MainAxisSize.min, groupValue: _imageMaxSize,
children: ImagePreferences.supportedSizes onChanged: (value) {
.map( if (value != null) _saveImageMaxSize(value);
(size) => RadioListTile<int>( Navigator.pop(context);
value: size, },
groupValue: _imageMaxSize, child: Column(
title: Text('${size}×$size px'), mainAxisSize: MainAxisSize.min,
subtitle: size == ImagePreferences.defaultMaxSize children: ImagePreferences.supportedSizes
? const Text('Default') .map(
: null, (size) => RadioListTile<int>(
onChanged: (value) { value: size,
if (value != null) _saveImageMaxSize(value); title: Text('$size×$size px'),
Navigator.pop(context); subtitle: size == ImagePreferences.defaultMaxSize
}, ? const Text('Default')
), : null,
) ),
.toList(), )
.toList(),
),
), ),
), ),
actions: [ actions: [