Merge branch 'main' into flutter-3.22

pull/1113/head
Krille-chan 1 year ago committed by GitHub
commit d9edf9f05b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -156,7 +156,8 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0) trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0) uber (< 0.2.0)
retriable (3.1.2) retriable (3.1.2)
rexml (3.2.5) rexml (3.2.8)
strscan (>= 3.0.9)
rouge (2.0.7) rouge (2.0.7)
ruby2_keywords (0.0.4) ruby2_keywords (0.0.4)
rubyzip (2.3.0) rubyzip (2.3.0)
@ -169,6 +170,7 @@ GEM
simctl (1.6.8) simctl (1.6.8)
CFPropertyList CFPropertyList
naturally naturally
strscan (3.1.0)
terminal-notifier (2.0.0) terminal-notifier (2.0.0)
terminal-table (1.8.0) terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1) unicode-display_width (~> 1.1, >= 1.1.1)

@ -610,7 +610,7 @@ class ChatController extends State<ChatPageWithRoom>
} }
} }
if (await Record().hasPermission() == false) return; if (await AudioRecorder().hasPermission() == false) return;
final result = await showDialog<RecordingResult>( final result = await showDialog<RecordingResult>(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,

@ -150,7 +150,8 @@ class ChatView extends StatelessWidget {
} }
}, },
child: StreamBuilder( child: StreamBuilder(
stream: controller.room.onUpdate.stream stream: controller.room.client.onRoomState.stream
.where((update) => update.roomId == controller.room.id)
.rateLimit(const Duration(seconds: 1)), .rateLimit(const Duration(seconds: 1)),
builder: (context, snapshot) => FutureBuilder( builder: (context, snapshot) => FutureBuilder(
future: controller.loadTimelineFuture, future: controller.loadTimelineFuture,

@ -144,11 +144,14 @@ class Message extends StatelessWidget {
setState(resetAnimateIn); setState(resetAnimateIn);
}); });
} }
return AnimatedSlide( return AnimatedSize(
offset: Offset(0, animateIn ? 1 : 0),
duration: FluffyThemes.animationDuration, duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve, curve: FluffyThemes.animationCurve,
child: Stack( clipBehavior: Clip.none,
alignment: ownMessage ? Alignment.bottomRight : Alignment.bottomLeft,
child: animateIn
? const SizedBox(height: 0, width: double.infinity)
: Stack(
children: [ children: [
Positioned( Positioned(
top: 0, top: 0,
@ -201,7 +204,8 @@ class Message extends StatelessWidget {
child: event.status == EventStatus.error child: event.status == EventStatus.error
? const Icon(Icons.error, color: Colors.red) ? const Icon(Icons.error, color: Colors.red)
: event.fileSendingStatus != null : event.fileSendingStatus != null
? const CircularProgressIndicator.adaptive( ? const CircularProgressIndicator
.adaptive(
strokeWidth: 1, strokeWidth: 1,
) )
: null, : null,
@ -212,8 +216,8 @@ class Message extends StatelessWidget {
FutureBuilder<User?>( FutureBuilder<User?>(
future: event.fetchSenderUser(), future: event.fetchSenderUser(),
builder: (context, snapshot) { builder: (context, snapshot) {
final user = final user = snapshot.data ??
snapshot.data ?? event.senderFromMemoryOrFallback; event.senderFromMemoryOrFallback;
return Avatar( return Avatar(
mxContent: user.avatarUrl, mxContent: user.avatarUrl,
name: user.calcDisplayname(), name: user.calcDisplayname(),
@ -231,26 +235,29 @@ class Message extends StatelessWidget {
children: [ children: [
if (!nextEventSameSender) if (!nextEventSameSender)
Padding( Padding(
padding: padding: const EdgeInsets.only(
const EdgeInsets.only(left: 8.0, bottom: 4), left: 8.0,
bottom: 4,
),
child: ownMessage || event.room.isDirectChat child: ownMessage || event.room.isDirectChat
? const SizedBox(height: 12) ? const SizedBox(height: 12)
: FutureBuilder<User?>( : FutureBuilder<User?>(
future: event.fetchSenderUser(), future: event.fetchSenderUser(),
builder: (context, snapshot) { builder: (context, snapshot) {
final displayname = final displayname = snapshot.data
snapshot.data?.calcDisplayname() ?? ?.calcDisplayname() ??
event.senderFromMemoryOrFallback event.senderFromMemoryOrFallback
.calcDisplayname(); .calcDisplayname();
return Text( return Text(
displayname, displayname,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: color: (Theme.of(context)
(Theme.of(context).brightness == .brightness ==
Brightness.light Brightness.light
? displayname.color ? displayname.color
: displayname.lightColorText), : displayname
.lightColorText),
), ),
); );
}, },
@ -278,7 +285,8 @@ class Message extends StatelessWidget {
duration: FluffyThemes.animationDuration, duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve, curve: FluffyThemes.animationCurve,
child: Material( child: Material(
color: noBubble ? Colors.transparent : color, color:
noBubble ? Colors.transparent : color,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius, borderRadius: borderRadius,
@ -296,7 +304,8 @@ class Message extends StatelessWidget {
vertical: 8, vertical: 8,
), ),
constraints: const BoxConstraints( constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 1.5, maxWidth:
FluffyThemes.columnWidth * 1.5,
), ),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -306,10 +315,14 @@ class Message extends StatelessWidget {
if (event.relationshipType == if (event.relationshipType ==
RelationshipTypes.reply) RelationshipTypes.reply)
FutureBuilder<Event?>( FutureBuilder<Event?>(
future: event.getReplyEvent(timeline), future: event
builder: .getReplyEvent(timeline),
(BuildContext context, snapshot) { builder: (
final replyEvent = snapshot.hasData BuildContext context,
snapshot,
) {
final replyEvent = snapshot
.hasData
? snapshot.data! ? snapshot.data!
: Event( : Event(
eventId: event eventId: event
@ -318,27 +331,33 @@ class Message extends StatelessWidget {
'msgtype': 'm.text', 'msgtype': 'm.text',
'body': '...', 'body': '...',
}, },
senderId: event.senderId, senderId:
type: 'm.room.message', event.senderId,
type:
'm.room.message',
room: event.room, room: event.room,
status: EventStatus.sent, status:
EventStatus.sent,
originServerTs: originServerTs:
DateTime.now(), DateTime.now(),
); );
return Padding( return Padding(
padding: const EdgeInsets.only( padding:
const EdgeInsets.only(
bottom: 4.0, bottom: 4.0,
), ),
child: InkWell( child: InkWell(
borderRadius: borderRadius: ReplyContent
ReplyContent.borderRadius, .borderRadius,
onTap: () => scrollToEventId( onTap: () =>
scrollToEventId(
replyEvent.eventId, replyEvent.eventId,
), ),
child: AbsorbPointer( child: AbsorbPointer(
child: ReplyContent( child: ReplyContent(
replyEvent, replyEvent,
ownMessage: ownMessage, ownMessage:
ownMessage,
timeline: timeline, timeline: timeline,
), ),
), ),
@ -361,18 +380,20 @@ class Message extends StatelessWidget {
top: 4.0, top: 4.0,
), ),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize:
MainAxisSize.min,
children: [ children: [
Icon( Icon(
Icons.edit_outlined, Icons.edit_outlined,
color: textColor.withAlpha(164), color: textColor
.withAlpha(164),
size: 14, size: 14,
), ),
Text( Text(
' - ${displayEvent.originServerTs.localizedTimeShort(context)}', ' - ${displayEvent.originServerTs.localizedTimeShort(context)}',
style: TextStyle( style: TextStyle(
color: color: textColor
textColor.withAlpha(164), .withAlpha(164),
fontSize: 12, fontSize: 12,
), ),
), ),

@ -9,7 +9,6 @@ import 'package:pasteboard/pasteboard.dart';
import 'package:slugify/slugify.dart'; import 'package:slugify/slugify.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/mxc_image.dart'; import 'package:fluffychat/widgets/mxc_image.dart';
import '../../widgets/avatar.dart'; import '../../widgets/avatar.dart';
@ -465,8 +464,11 @@ class InputBar extends StatelessWidget {
mimeType: content.mimeType, mimeType: content.mimeType,
bytes: data, bytes: data,
name: content.uri.split('/').last, name: content.uri.split('/').last,
).detectFileType; );
room.sendFileEvent(file, shrinkImageMaxDimension: 1600); room.sendFileEvent(
file,
shrinkImageMaxDimension: 1600,
);
}, },
), ),
minLines: minLines, minLines: minLines,

@ -28,16 +28,16 @@ class RecordingDialogState extends State<RecordingDialog> {
bool error = false; bool error = false;
String? _recordedPath; String? _recordedPath;
final _audioRecorder = Record(); final _audioRecorder = AudioRecorder();
final List<double> amplitudeTimeline = []; final List<double> amplitudeTimeline = [];
static const int bitRate = 64000; static const int bitRate = 64000;
static const int samplingRate = 22050; static const int samplingRate = 44100;
Future<void> startRecording() async { Future<void> startRecording() async {
try { try {
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
_recordedPath = final path = _recordedPath =
'${tempDir.path}/recording${DateTime.now().microsecondsSinceEpoch}.${RecordingDialog.recordingFileType}'; '${tempDir.path}/recording${DateTime.now().microsecondsSinceEpoch}.${RecordingDialog.recordingFileType}';
final result = await _audioRecorder.hasPermission(); final result = await _audioRecorder.hasPermission();
@ -47,9 +47,15 @@ class RecordingDialogState extends State<RecordingDialog> {
} }
await WakelockPlus.enable(); await WakelockPlus.enable();
await _audioRecorder.start( await _audioRecorder.start(
path: _recordedPath, const RecordConfig(
bitRate: bitRate, bitRate: bitRate,
samplingRate: samplingRate, sampleRate: samplingRate,
numChannels: 1,
autoGain: true,
echoCancel: true,
noiseSuppress: true,
),
path: path,
); );
setState(() => _duration = Duration.zero); setState(() => _duration = Duration.zero);
_recorderSubscription?.cancel(); _recorderSubscription?.cancel();

@ -14,18 +14,26 @@ class TypingIndicators extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder<Object>(
stream: controller.room.client.onSync.stream.where(
(syncUpdate) =>
syncUpdate.rooms?.join?[controller.room.id]?.ephemeral
?.any((ephemeral) => ephemeral.type == 'm.typing') ??
false,
),
builder: (context, _) {
final typingUsers = controller.room.typingUsers final typingUsers = controller.room.typingUsers
..removeWhere((u) => u.stateKey == Matrix.of(context).client.userID); ..removeWhere((u) => u.stateKey == Matrix.of(context).client.userID);
const topPadding = 20.0; const topPadding = 20.0;
const bottomPadding = 4.0; const bottomPadding = 4.0;
return Container( return Container(
width: double.infinity, width: double.infinity,
alignment: Alignment.center, alignment: Alignment.center,
child: AnimatedContainer( child: AnimatedContainer(
constraints: constraints:
const BoxConstraints(maxWidth: FluffyThemes.columnWidth * 2.5), const BoxConstraints(maxWidth: FluffyThemes.columnWidth * 2.5),
height: typingUsers.isEmpty ? 0 : Avatar.defaultSize + bottomPadding, height:
typingUsers.isEmpty ? 0 : Avatar.defaultSize + bottomPadding,
duration: FluffyThemes.animationDuration, duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve, curve: FluffyThemes.animationCurve,
alignment: controller.timeline!.events.isNotEmpty && alignment: controller.timeline!.events.isNotEmpty &&
@ -89,6 +97,8 @@ class TypingIndicators extends StatelessWidget {
), ),
), ),
); );
},
);
} }
} }

@ -22,7 +22,8 @@ class ChatAccessSettingsPageView extends StatelessWidget {
), ),
body: MaxWidthBody( body: MaxWidthBody(
child: StreamBuilder<Object>( child: StreamBuilder<Object>(
stream: room.onUpdate.stream, stream: room.client.onRoomState.stream
.where((update) => update.roomId == controller.room.id),
builder: (context, snapshot) { builder: (context, snapshot) {
final canonicalAlias = room.canonicalAlias; final canonicalAlias = room.canonicalAlias;
final altAliases = room final altAliases = room

@ -36,7 +36,8 @@ class ChatDetailsView extends StatelessWidget {
} }
return StreamBuilder( return StreamBuilder(
stream: room.onUpdate.stream, stream: room.client.onRoomState.stream
.where((update) => update.roomId == room.id),
builder: (context, snapshot) { builder: (context, snapshot) {
var members = room.getParticipants().toList() var members = room.getParticipants().toList()
..sort((b, a) => a.powerLevel.compareTo(b.powerLevel)); ..sort((b, a) => a.powerLevel.compareTo(b.powerLevel));

@ -82,7 +82,8 @@ class ChatEncryptionSettingsView extends StatelessWidget {
), ),
), ),
StreamBuilder( StreamBuilder(
stream: room.onUpdate.stream, stream: room.client.onRoomState.stream
.where((update) => update.roomId == controller.room.id),
builder: (context, snapshot) => builder: (context, snapshot) =>
FutureBuilder<List<DeviceKeys>>( FutureBuilder<List<DeviceKeys>>(
future: room.getUserDeviceKeys(), future: room.getUserDeviceKeys(),

@ -64,7 +64,8 @@ class InvitationSelectionView extends StatelessWidget {
), ),
), ),
StreamBuilder<Object>( StreamBuilder<Object>(
stream: room.onUpdate.stream, stream: room.client.onRoomState.stream
.where((update) => update.roomId == room.id),
builder: (context, snapshot) { builder: (context, snapshot) {
final participants = final participants =
room.getParticipants().map((user) => user.id).toSet(); room.getParticipants().map((user) => user.id).toSet();

@ -21,7 +21,8 @@ class MultipleEmotesSettingsView extends StatelessWidget {
title: Text(L10n.of(context)!.emotePacks), title: Text(L10n.of(context)!.emotePacks),
), ),
body: StreamBuilder( body: StreamBuilder(
stream: room.onUpdate.stream, stream: room.client.onRoomState.stream
.where((update) => update.roomId == room.id),
builder: (context, snapshot) { builder: (context, snapshot) {
final packStateEvents = room.states['im.ponies.room_emotes']; final packStateEvents = room.states['im.ponies.room_emotes'];
// we need to manually convert the map using Map.of, otherwise assigning null will throw a type error. // we need to manually convert the map using Map.of, otherwise assigning null will throw a type error.

@ -120,6 +120,7 @@ abstract class ClientManager {
}, },
nativeImplementations: nativeImplementations, nativeImplementations: nativeImplementations,
customImageResizer: PlatformInfos.isMobile ? customImageResizer : null, customImageResizer: PlatformInfos.isMobile ? customImageResizer : null,
defaultNetworkRequestTimeout: const Duration(minutes: 5),
enableDehydratedDevices: true, enableDehydratedDevices: true,
); );
} }

@ -35,6 +35,12 @@ Future<DatabaseApi> flutterMatrixSdkDatabaseBuilder(Client client) async {
), ),
); );
// Delete database file:
if (database == null && !kIsWeb) {
final dbFile = File(await _getDatabasePath(client.clientName));
if (await dbFile.exists()) await dbFile.delete();
}
try { try {
// Send error notification: // Send error notification:
final l10n = lookupL10n(PlatformDispatcher.instance.locale); final l10n = lookupL10n(PlatformDispatcher.instance.locale);
@ -61,9 +67,6 @@ Future<MatrixSdkDatabase> _constructDatabase(Client client) async {
final cipher = await getDatabaseCipher(); final cipher = await getDatabaseCipher();
final databaseDirectory = PlatformInfos.isIOS || PlatformInfos.isMacOS
? await getLibraryDirectory()
: await getApplicationSupportDirectory();
Directory? fileStorageLocation; Directory? fileStorageLocation;
try { try {
fileStorageLocation = await getTemporaryDirectory(); fileStorageLocation = await getTemporaryDirectory();
@ -73,7 +76,7 @@ Future<MatrixSdkDatabase> _constructDatabase(Client client) async {
); );
} }
final path = join(databaseDirectory.path, '${client.clientName}.sqlite'); final path = await _getDatabasePath(client.clientName);
// fix dlopen for old Android // fix dlopen for old Android
await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions(); await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions();
@ -118,6 +121,14 @@ Future<MatrixSdkDatabase> _constructDatabase(Client client) async {
); );
} }
Future<String> _getDatabasePath(String clientName) async {
final databaseDirectory = PlatformInfos.isIOS || PlatformInfos.isMacOS
? await getLibraryDirectory()
: await getApplicationSupportDirectory();
return join(databaseDirectory.path, '$clientName.sqlite');
}
Future<void> _migrateLegacyLocation( Future<void> _migrateLegacyLocation(
String sqlFilePath, String sqlFilePath,
String clientName, String clientName,

@ -24,7 +24,7 @@ import macos_window_utils
import package_info_plus import package_info_plus
import pasteboard import pasteboard
import path_provider_foundation import path_provider_foundation
import record_macos import record_darwin
import share_plus import share_plus
import shared_preferences_foundation import shared_preferences_foundation
import sqflite import sqflite
@ -55,7 +55,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
RecordMacosPlugin.register(with: registry.registrar(forPlugin: "RecordMacosPlugin")) RecordPlugin.register(with: registry.registrar(forPlugin: "RecordPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))

@ -1210,10 +1210,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: matrix name: matrix
sha256: "8610e6d207d6b667e4fe9e769d5b479db27aa1f80570880d3f171a5d3ff49d1a" sha256: b96f16ec227138a61d148f2812c4d558b2930edbb6cd05d03b3a41c4fffd2f47
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.29.2" version: "0.29.7"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -1618,50 +1618,58 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: record name: record
sha256: f703397f5a60d9b2b655b3acc94ba079b2d9a67dc0725bdb90ef2fee2441ebf7 sha256: "113b368168c49c78902ab37c2b354dea30a0aec5bdeca434073826b6ea73eca1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.4.4" version: "5.0.5"
record_linux: record_android:
dependency: transitive dependency: transitive
description: description:
name: record_linux name: record_android
sha256: "348db92c4ec1b67b1b85d791381c8c99d7c6908de141e7c9edc20dad399b15ce" sha256: "0df98e05873b22b443309e289bf1eb3b5b9a60e7779134334e2073eb0763a992"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.1" version: "1.1.0"
record_macos: record_darwin:
dependency: transitive
description:
name: record_darwin
sha256: ee8cb1bb1712d7ce38140ecabe70e5c286c02f05296d66043bee865ace7eb1b9
url: "https://pub.dev"
source: hosted
version: "1.0.1"
record_linux:
dependency: transitive dependency: transitive
description: description:
name: record_macos name: record_linux
sha256: d1d0199d1395f05e218207e8cacd03eb9dc9e256ddfe2cfcbbb90e8edea06057 sha256: "7d0e70cd51635128fe9d37d89bafd6011d7cbba9af8dc323079ae60f23546aef"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.2" version: "0.7.1"
record_platform_interface: record_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: record_platform_interface name: record_platform_interface
sha256: "7a2d4ce7ac3752505157e416e4e0d666a54b1d5d8601701b7e7e5e30bec181b4" sha256: "3a4b56e94ecd2a0b2b43eb1fa6f94c5b8484334f5d38ef43959c4bf97fb374cf"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.0" version: "1.0.2"
record_web: record_web:
dependency: transitive dependency: transitive
description: description:
name: record_web name: record_web
sha256: "219ffb4ca59b4338117857db56d3ffadbde3169bcaf1136f5f4d4656f4a2372d" sha256: "24847cdbcf999f7a5762170792f622ac844858766becd0f2370ec8ae22f7526e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.0" version: "1.0.5"
record_windows: record_windows:
dependency: transitive dependency: transitive
description: description:
name: record_windows name: record_windows
sha256: "42d545155a26b20d74f5107648dbb3382dbbc84dc3f1adc767040359e57a1345" sha256: "39998b3ea7d8d28b04159d82220e6e5e32a7c357c6fb2794f5736beea272f6c3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.1" version: "1.0.2"
remove_emoji: remove_emoji:
dependency: transitive dependency: transitive
description: description:

@ -64,8 +64,8 @@ dependencies:
keyboard_shortcuts: ^0.1.4 keyboard_shortcuts: ^0.1.4
latlong2: ^0.9.1 latlong2: ^0.9.1
linkify: ^5.0.0 linkify: ^5.0.0
matrix: ^0.29.2 matrix: ^0.29.7
native_imaging: ^0.1.0 native_imaging: ^0.1.1
package_info_plus: ^6.0.0 package_info_plus: ^6.0.0
pasteboard: ^0.2.0 pasteboard: ^0.2.0
path: ^1.9.0 path: ^1.9.0
@ -76,7 +76,7 @@ dependencies:
punycode: ^1.0.0 punycode: ^1.0.0
qr_code_scanner: ^1.0.1 qr_code_scanner: ^1.0.1
receive_sharing_intent: 1.4.5 # Update needs more work receive_sharing_intent: 1.4.5 # Update needs more work
record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS record: ^5.0.5
scroll_to_index: ^3.0.1 scroll_to_index: ^3.0.1
share_plus: ^9.0.0 share_plus: ^9.0.0
shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401 shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401

Loading…
Cancel
Save