mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-27 14:59:29 +01:00
swith to event aggregations and render message edits and reactions
This commit is contained in:
parent
2db8016f58
commit
81a6530ed8
@ -1,6 +1,10 @@
|
|||||||
# Version 0.17.0 - 2020-08-??
|
# Version 0.17.0 - 2020-08-??
|
||||||
### Features:
|
### Features
|
||||||
- Pin and unpin chats
|
- Pin and unpin chats
|
||||||
|
- Implement event aggregations
|
||||||
|
- Implement message edits
|
||||||
|
- Render reactions
|
||||||
|
- Add / Remove reactions by tapping on existing reactions
|
||||||
### Fixes:
|
### Fixes:
|
||||||
- Don't re-render the room list nearly as often, increasing performance
|
- Don't re-render the room list nearly as often, increasing performance
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import 'package:flutter/material.dart';
|
|||||||
import '../adaptive_page_layout.dart';
|
import '../adaptive_page_layout.dart';
|
||||||
import '../avatar.dart';
|
import '../avatar.dart';
|
||||||
import '../matrix.dart';
|
import '../matrix.dart';
|
||||||
|
import '../message_reactions.dart';
|
||||||
import 'state_message.dart';
|
import 'state_message.dart';
|
||||||
|
|
||||||
class Message extends StatelessWidget {
|
class Message extends StatelessWidget {
|
||||||
@ -64,11 +65,13 @@ class Message extends StatelessWidget {
|
|||||||
var rowMainAxisAlignment =
|
var rowMainAxisAlignment =
|
||||||
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;
|
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;
|
||||||
|
|
||||||
|
final displayEvent = event.getDisplayEvent(timeline);
|
||||||
|
|
||||||
if (event.showThumbnail) {
|
if (event.showThumbnail) {
|
||||||
color = Theme.of(context).scaffoldBackgroundColor.withOpacity(0.66);
|
color = Theme.of(context).scaffoldBackgroundColor.withOpacity(0.66);
|
||||||
textColor = Theme.of(context).textTheme.bodyText2.color;
|
textColor = Theme.of(context).textTheme.bodyText2.color;
|
||||||
} else if (ownMessage) {
|
} else if (ownMessage) {
|
||||||
color = event.status == -1
|
color = displayEvent.status == -1
|
||||||
? Colors.redAccent
|
? Colors.redAccent
|
||||||
: Theme.of(context).primaryColor;
|
: Theme.of(context).primaryColor;
|
||||||
}
|
}
|
||||||
@ -91,15 +94,14 @@ class Message extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (event.isReply)
|
if (event.relationshipType == RelationshipTypes.Reply)
|
||||||
FutureBuilder<Event>(
|
FutureBuilder<Event>(
|
||||||
future: event.getReplyEvent(timeline),
|
future: event.getReplyEvent(timeline),
|
||||||
builder: (BuildContext context, snapshot) {
|
builder: (BuildContext context, snapshot) {
|
||||||
final replyEvent = snapshot.hasData
|
final replyEvent = snapshot.hasData
|
||||||
? snapshot.data
|
? snapshot.data
|
||||||
: Event(
|
: Event(
|
||||||
eventId: event.content['m.relates_to']
|
eventId: event.relationshipEventId,
|
||||||
['m.in_reply_to']['event_id'],
|
|
||||||
content: {'msgtype': 'm.text', 'body': '...'},
|
content: {'msgtype': 'm.text', 'body': '...'},
|
||||||
senderId: event.senderId,
|
senderId: event.senderId,
|
||||||
type: 'm.room.message',
|
type: 'm.room.message',
|
||||||
@ -110,18 +112,18 @@ class Message extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.symmetric(vertical: 4.0),
|
margin: EdgeInsets.symmetric(vertical: 4.0),
|
||||||
child:
|
child: ReplyContent(replyEvent,
|
||||||
ReplyContent(replyEvent, lightText: ownMessage),
|
lightText: ownMessage, timeline: timeline),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MessageContent(
|
MessageContent(
|
||||||
event,
|
displayEvent,
|
||||||
textColor: textColor,
|
textColor: textColor,
|
||||||
),
|
),
|
||||||
if (event.type == EventTypes.Encrypted &&
|
if (displayEvent.type == EventTypes.Encrypted &&
|
||||||
event.messageType == MessageTypes.BadEncrypted &&
|
displayEvent.messageType == MessageTypes.BadEncrypted &&
|
||||||
event.content['can_request_session'] == true)
|
displayEvent.content['can_request_session'] == true)
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
color: color.withAlpha(100),
|
color: color.withAlpha(100),
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -129,15 +131,18 @@ class Message extends StatelessWidget {
|
|||||||
style: TextStyle(color: textColor),
|
style: TextStyle(color: textColor),
|
||||||
),
|
),
|
||||||
onPressed: () => SimpleDialogs(context)
|
onPressed: () => SimpleDialogs(context)
|
||||||
.tryRequestWithLoadingDialog(event.requestKey()),
|
.tryRequestWithLoadingDialog(
|
||||||
|
displayEvent.requestKey()),
|
||||||
),
|
),
|
||||||
SizedBox(height: 4),
|
SizedBox(height: 4),
|
||||||
Opacity(
|
Opacity(
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
child: _MetaRow(
|
child: _MetaRow(
|
||||||
event,
|
event, // meta information should be from the unedited event
|
||||||
ownMessage,
|
ownMessage,
|
||||||
textColor,
|
textColor,
|
||||||
|
timeline,
|
||||||
|
displayEvent,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -150,6 +155,8 @@ class Message extends StatelessWidget {
|
|||||||
event,
|
event,
|
||||||
ownMessage,
|
ownMessage,
|
||||||
textColor,
|
textColor,
|
||||||
|
timeline,
|
||||||
|
displayEvent,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -170,6 +177,32 @@ class Message extends StatelessWidget {
|
|||||||
} else {
|
} else {
|
||||||
rowChildren.insert(0, avatarOrSizedBox);
|
rowChildren.insert(0, avatarOrSizedBox);
|
||||||
}
|
}
|
||||||
|
final row = Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisAlignment: rowMainAxisAlignment,
|
||||||
|
children: rowChildren,
|
||||||
|
);
|
||||||
|
Widget container;
|
||||||
|
if (event.hasAggregatedEvents(timeline, RelationshipTypes.Reaction)) {
|
||||||
|
container = Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment:
|
||||||
|
ownMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
row,
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: 4.0,
|
||||||
|
left: (ownMessage ? 0 : Avatar.defaultSize) + 12.0,
|
||||||
|
right: (ownMessage ? Avatar.defaultSize : 0) + 12.0,
|
||||||
|
),
|
||||||
|
child: MessageReactions(event, timeline),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
container = row;
|
||||||
|
}
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onHover: (b) => useMouse = true,
|
onHover: (b) => useMouse = true,
|
||||||
@ -185,11 +218,7 @@ class Message extends StatelessWidget {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 8.0, right: 8.0, bottom: sameSender ? 4.0 : 8.0),
|
left: 8.0, right: 8.0, bottom: sameSender ? 4.0 : 8.0),
|
||||||
child: Row(
|
child: container,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
mainAxisAlignment: rowMainAxisAlignment,
|
|
||||||
children: rowChildren,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -200,8 +229,12 @@ class _MetaRow extends StatelessWidget {
|
|||||||
final Event event;
|
final Event event;
|
||||||
final bool ownMessage;
|
final bool ownMessage;
|
||||||
final Color color;
|
final Color color;
|
||||||
|
final Timeline timeline;
|
||||||
|
final Event displayEvent;
|
||||||
|
|
||||||
const _MetaRow(this.event, this.ownMessage, this.color, {Key key})
|
const _MetaRow(
|
||||||
|
this.event, this.ownMessage, this.color, this.timeline, this.displayEvent,
|
||||||
|
{Key key})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -229,10 +262,16 @@ class _MetaRow extends StatelessWidget {
|
|||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (event.hasAggregatedEvents(timeline, RelationshipTypes.Edit))
|
||||||
|
Icon(
|
||||||
|
Icons.edit,
|
||||||
|
size: 12,
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
if (ownMessage) SizedBox(width: 2),
|
if (ownMessage) SizedBox(width: 2),
|
||||||
if (ownMessage)
|
if (ownMessage)
|
||||||
Icon(
|
Icon(
|
||||||
event.statusIcon,
|
displayEvent.statusIcon,
|
||||||
size: 12,
|
size: 12,
|
||||||
color: color,
|
color: color,
|
||||||
),
|
),
|
||||||
|
@ -194,7 +194,6 @@ class MatrixState extends State<Matrix> {
|
|||||||
verificationMethods.add(KeyVerificationMethod.emoji);
|
verificationMethods.add(KeyVerificationMethod.emoji);
|
||||||
}
|
}
|
||||||
client = Client(widget.clientName,
|
client = Client(widget.clientName,
|
||||||
debug: false,
|
|
||||||
enableE2eeRecovery: true,
|
enableE2eeRecovery: true,
|
||||||
verificationMethods: verificationMethods,
|
verificationMethods: verificationMethods,
|
||||||
importantStateEvents: <String>{
|
importantStateEvents: <String>{
|
||||||
|
@ -40,7 +40,6 @@ class MessageContent extends StatelessWidget {
|
|||||||
case MessageTypes.Text:
|
case MessageTypes.Text:
|
||||||
case MessageTypes.Notice:
|
case MessageTypes.Notice:
|
||||||
case MessageTypes.Emote:
|
case MessageTypes.Emote:
|
||||||
case MessageTypes.Reply:
|
|
||||||
if (Matrix.of(context).renderHtml &&
|
if (Matrix.of(context).renderHtml &&
|
||||||
!event.redacted &&
|
!event.redacted &&
|
||||||
event.content['format'] == 'org.matrix.custom.html' &&
|
event.content['format'] == 'org.matrix.custom.html' &&
|
||||||
|
140
lib/components/message_reactions.dart
Normal file
140
lib/components/message_reactions.dart
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_advanced_networkimage/provider.dart';
|
||||||
|
|
||||||
|
import 'matrix.dart';
|
||||||
|
|
||||||
|
class MessageReactions extends StatelessWidget {
|
||||||
|
final Event event;
|
||||||
|
final Timeline timeline;
|
||||||
|
|
||||||
|
const MessageReactions(this.event, this.timeline);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final allReactionEvents =
|
||||||
|
event.aggregatedEvents(timeline, RelationshipTypes.Reaction);
|
||||||
|
final reactionMap = <String, _ReactionEntry>{};
|
||||||
|
for (final e in allReactionEvents) {
|
||||||
|
if (e.content['m.relates_to'].containsKey('key')) {
|
||||||
|
final key = e.content['m.relates_to']['key'];
|
||||||
|
if (!reactionMap.containsKey(key)) {
|
||||||
|
reactionMap[key] = _ReactionEntry(
|
||||||
|
key: key,
|
||||||
|
count: 0,
|
||||||
|
reacted: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
reactionMap[key].count++;
|
||||||
|
reactionMap[key].reacted |= e.senderId == e.room.client.userID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final reactionList = reactionMap.values.toList();
|
||||||
|
reactionList.sort((a, b) => b.count - a.count > 0 ? 1 : -1);
|
||||||
|
return Wrap(
|
||||||
|
spacing: 4.0,
|
||||||
|
runSpacing: 4.0,
|
||||||
|
children: reactionList
|
||||||
|
.map((r) => _Reaction(
|
||||||
|
reactionKey: r.key,
|
||||||
|
count: r.count,
|
||||||
|
reacted: r.reacted,
|
||||||
|
onTap: () {
|
||||||
|
if (r.reacted) {
|
||||||
|
final evt = allReactionEvents.firstWhere(
|
||||||
|
(e) =>
|
||||||
|
e.senderId == e.room.client.userID &&
|
||||||
|
e.content['m.relates_to']['key'] == r.key,
|
||||||
|
orElse: () => null);
|
||||||
|
if (evt != null) {
|
||||||
|
evt.redact();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.room.sendReaction(event.eventId, r.key);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Reaction extends StatelessWidget {
|
||||||
|
final String reactionKey;
|
||||||
|
final int count;
|
||||||
|
final bool reacted;
|
||||||
|
final void Function() onTap;
|
||||||
|
|
||||||
|
const _Reaction({this.reactionKey, this.count, this.reacted, this.onTap});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final borderColor = reacted ? Colors.red : Theme.of(context).primaryColor;
|
||||||
|
final textColor = Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Colors.white
|
||||||
|
: Colors.black;
|
||||||
|
final color = Theme.of(context).secondaryHeaderColor;
|
||||||
|
final fontSize = DefaultTextStyle.of(context).style.fontSize;
|
||||||
|
final padding = fontSize / 5;
|
||||||
|
Widget content;
|
||||||
|
if (reactionKey.startsWith('mxc://')) {
|
||||||
|
final src = Uri.parse(reactionKey)?.getThumbnail(
|
||||||
|
Matrix.of(context).client,
|
||||||
|
width: 9999,
|
||||||
|
height: fontSize * MediaQuery.of(context).devicePixelRatio,
|
||||||
|
method: ThumbnailMethod.scale,
|
||||||
|
);
|
||||||
|
content = Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Image(
|
||||||
|
image: AdvancedNetworkImage(
|
||||||
|
src,
|
||||||
|
useDiskCache: !kIsWeb,
|
||||||
|
),
|
||||||
|
height: fontSize,
|
||||||
|
),
|
||||||
|
Text(count.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: textColor,
|
||||||
|
fontSize: DefaultTextStyle.of(context).style.fontSize,
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var renderKey = reactionKey;
|
||||||
|
if (renderKey.length > 10) {
|
||||||
|
renderKey = renderKey.substring(0, 7) + '...';
|
||||||
|
}
|
||||||
|
content = Text('$renderKey $count',
|
||||||
|
style: TextStyle(
|
||||||
|
color: textColor,
|
||||||
|
fontSize: DefaultTextStyle.of(context).style.fontSize,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return InkWell(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color,
|
||||||
|
border: Border.all(
|
||||||
|
width: fontSize / 20,
|
||||||
|
color: borderColor,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(padding * 2)),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.all(padding),
|
||||||
|
child: content,
|
||||||
|
),
|
||||||
|
onTap: () => onTap != null ? onTap() : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReactionEntry {
|
||||||
|
String key;
|
||||||
|
int count;
|
||||||
|
bool reacted;
|
||||||
|
|
||||||
|
_ReactionEntry({this.key, this.count, this.reacted});
|
||||||
|
}
|
@ -8,23 +8,29 @@ import 'matrix.dart';
|
|||||||
class ReplyContent extends StatelessWidget {
|
class ReplyContent extends StatelessWidget {
|
||||||
final Event replyEvent;
|
final Event replyEvent;
|
||||||
final bool lightText;
|
final bool lightText;
|
||||||
|
final Timeline timeline;
|
||||||
|
|
||||||
const ReplyContent(this.replyEvent, {this.lightText = false, Key key})
|
const ReplyContent(this.replyEvent,
|
||||||
|
{this.lightText = false, Key key, this.timeline})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Widget replyBody;
|
Widget replyBody;
|
||||||
if (replyEvent != null &&
|
final displayEvent = replyEvent != null && timeline != null
|
||||||
|
? replyEvent.getDisplayEvent(timeline)
|
||||||
|
: replyEvent;
|
||||||
|
if (displayEvent != null &&
|
||||||
Matrix.of(context).renderHtml &&
|
Matrix.of(context).renderHtml &&
|
||||||
[EventTypes.Message, EventTypes.Encrypted].contains(replyEvent.type) &&
|
[EventTypes.Message, EventTypes.Encrypted]
|
||||||
|
.contains(displayEvent.type) &&
|
||||||
[MessageTypes.Text, MessageTypes.Notice, MessageTypes.Emote]
|
[MessageTypes.Text, MessageTypes.Notice, MessageTypes.Emote]
|
||||||
.contains(replyEvent.messageType) &&
|
.contains(displayEvent.messageType) &&
|
||||||
!replyEvent.redacted &&
|
!displayEvent.redacted &&
|
||||||
replyEvent.content['format'] == 'org.matrix.custom.html' &&
|
displayEvent.content['format'] == 'org.matrix.custom.html' &&
|
||||||
replyEvent.content['formatted_body'] is String) {
|
displayEvent.content['formatted_body'] is String) {
|
||||||
String html = replyEvent.content['formatted_body'];
|
String html = displayEvent.content['formatted_body'];
|
||||||
if (replyEvent.messageType == MessageTypes.Emote) {
|
if (displayEvent.messageType == MessageTypes.Emote) {
|
||||||
html = '* $html';
|
html = '* $html';
|
||||||
}
|
}
|
||||||
replyBody = HtmlMessage(
|
replyBody = HtmlMessage(
|
||||||
@ -36,11 +42,11 @@ class ReplyContent extends StatelessWidget {
|
|||||||
fontSize: DefaultTextStyle.of(context).style.fontSize,
|
fontSize: DefaultTextStyle.of(context).style.fontSize,
|
||||||
),
|
),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
room: replyEvent.room,
|
room: displayEvent.room,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
replyBody = Text(
|
replyBody = Text(
|
||||||
replyEvent?.getLocalizedBody(
|
displayEvent?.getLocalizedBody(
|
||||||
L10n.of(context),
|
L10n.of(context),
|
||||||
withSenderNamePrefix: false,
|
withSenderNamePrefix: false,
|
||||||
hideReply: true,
|
hideReply: true,
|
||||||
@ -71,7 +77,7 @@ class ReplyContent extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
(replyEvent?.sender?.calcDisplayname() ?? '') + ':',
|
(displayEvent?.sender?.calcDisplayname() ?? '') + ':',
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -8,6 +8,18 @@ import 'package:moor/moor.dart';
|
|||||||
import 'package:moor/isolate.dart';
|
import 'package:moor/isolate.dart';
|
||||||
import 'cipher_db.dart' as cipher;
|
import 'cipher_db.dart' as cipher;
|
||||||
|
|
||||||
|
class DatabaseNoTransactions extends Database {
|
||||||
|
DatabaseNoTransactions.connect(DatabaseConnection connection)
|
||||||
|
: super.connect(connection);
|
||||||
|
|
||||||
|
// moor transactions are sometimes rather weird and freeze. Until there is a
|
||||||
|
// proper fix in moor we override that there aren't actually using transactions
|
||||||
|
@override
|
||||||
|
Future<T> transaction<T>(Future<T> Function() action) async {
|
||||||
|
return action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool _inited = false;
|
bool _inited = false;
|
||||||
|
|
||||||
// see https://moor.simonbinder.eu/docs/advanced-features/isolates/
|
// see https://moor.simonbinder.eu/docs/advanced-features/isolates/
|
||||||
@ -57,7 +69,7 @@ Future<Database> constructDb(
|
|||||||
receivePort.sendPort, targetPath, password, logStatements),
|
receivePort.sendPort, targetPath, password, logStatements),
|
||||||
);
|
);
|
||||||
final isolate = (await receivePort.first as MoorIsolate);
|
final isolate = (await receivePort.first as MoorIsolate);
|
||||||
return Database.connect(await isolate.connect());
|
return DatabaseNoTransactions.connect(await isolate.connect());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getLocalstorage(String key) async {
|
Future<String> getLocalstorage(String key) async {
|
||||||
|
@ -161,7 +161,7 @@ abstract class FirebaseController {
|
|||||||
} else {
|
} else {
|
||||||
final platform = kIsWeb ? 'Web' : Platform.operatingSystem;
|
final platform = kIsWeb ? 'Web' : Platform.operatingSystem;
|
||||||
final clientName = 'FluffyChat $platform';
|
final clientName = 'FluffyChat $platform';
|
||||||
client = Client(clientName, debug: false);
|
client = Client(clientName);
|
||||||
client.database = await getDatabase(client);
|
client.database = await getDatabase(client);
|
||||||
client.connect();
|
client.connect();
|
||||||
await client.onLoginStateChanged.stream
|
await client.onLoginStateChanged.stream
|
||||||
|
@ -76,6 +76,8 @@ class _ChatState extends State<_Chat> {
|
|||||||
|
|
||||||
Event replyEvent;
|
Event replyEvent;
|
||||||
|
|
||||||
|
Event editEvent;
|
||||||
|
|
||||||
bool showScrollDownButton = false;
|
bool showScrollDownButton = false;
|
||||||
|
|
||||||
bool get selectMode => selectedEvents.isNotEmpty;
|
bool get selectMode => selectedEvents.isNotEmpty;
|
||||||
@ -174,13 +176,15 @@ class _ChatState extends State<_Chat> {
|
|||||||
|
|
||||||
void send() {
|
void send() {
|
||||||
if (sendController.text.isEmpty) return;
|
if (sendController.text.isEmpty) return;
|
||||||
room.sendTextEvent(sendController.text, inReplyTo: replyEvent);
|
room.sendTextEvent(sendController.text,
|
||||||
|
inReplyTo: replyEvent, editEventId: editEvent?.eventId);
|
||||||
sendController.text = '';
|
sendController.text = '';
|
||||||
if (replyEvent != null) {
|
|
||||||
setState(() => replyEvent = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(() => inputText = '');
|
setState(() {
|
||||||
|
inputText = '';
|
||||||
|
replyEvent = null;
|
||||||
|
editEvent = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendFileAction(BuildContext context) async {
|
void sendFileAction(BuildContext context) async {
|
||||||
@ -289,8 +293,17 @@ class _ChatState extends State<_Chat> {
|
|||||||
Navigator.of(context).popUntil((r) => r.isFirst);
|
Navigator.of(context).popUntil((r) => r.isFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendAgainAction() {
|
void sendAgainAction(Timeline timeline) {
|
||||||
selectedEvents.first.sendAgain();
|
final event = selectedEvents.first;
|
||||||
|
if (event.status == -1) {
|
||||||
|
event.sendAgain();
|
||||||
|
}
|
||||||
|
final allEditEvents = event
|
||||||
|
.aggregatedEvents(timeline, RelationshipTypes.Edit)
|
||||||
|
.where((e) => e.status == -1);
|
||||||
|
for (final e in allEditEvents) {
|
||||||
|
e.sendAgain();
|
||||||
|
}
|
||||||
setState(() => selectedEvents.clear());
|
setState(() => selectedEvents.clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,6 +424,23 @@ class _ChatState extends State<_Chat> {
|
|||||||
.numberSelected(selectedEvents.length.toString())),
|
.numberSelected(selectedEvents.length.toString())),
|
||||||
actions: selectMode
|
actions: selectMode
|
||||||
? <Widget>[
|
? <Widget>[
|
||||||
|
if (selectedEvents.length == 1 &&
|
||||||
|
selectedEvents.first.status > 0 &&
|
||||||
|
selectedEvents.first.senderId == client.userID)
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.edit),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
editEvent = selectedEvents.first;
|
||||||
|
sendController.text = editEvent
|
||||||
|
.getDisplayEvent(timeline)
|
||||||
|
.getLocalizedBody(L10n.of(context),
|
||||||
|
withSenderNamePrefix: false, hideReply: true);
|
||||||
|
selectedEvents.clear();
|
||||||
|
});
|
||||||
|
inputFocus.requestFocus();
|
||||||
|
},
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.content_copy),
|
icon: Icon(Icons.content_copy),
|
||||||
onPressed: () => copyEventsAction(context),
|
onPressed: () => copyEventsAction(context),
|
||||||
@ -467,7 +497,16 @@ class _ChatState extends State<_Chat> {
|
|||||||
room.sendReadReceipt(timeline.events.first.eventId);
|
room.sendReadReceipt(timeline.events.first.eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeline.events.isEmpty) return Container();
|
final filteredEvents = timeline.events
|
||||||
|
.where((e) =>
|
||||||
|
![
|
||||||
|
RelationshipTypes.Edit,
|
||||||
|
RelationshipTypes.Reaction
|
||||||
|
].contains(e.relationshipType) &&
|
||||||
|
e.type != 'm.reaction')
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (filteredEvents.isEmpty) return Container();
|
||||||
|
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
@ -479,10 +518,10 @@ class _ChatState extends State<_Chat> {
|
|||||||
2),
|
2),
|
||||||
),
|
),
|
||||||
reverse: true,
|
reverse: true,
|
||||||
itemCount: timeline.events.length + 2,
|
itemCount: filteredEvents.length + 2,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
itemBuilder: (BuildContext context, int i) {
|
itemBuilder: (BuildContext context, int i) {
|
||||||
return i == timeline.events.length + 1
|
return i == filteredEvents.length + 1
|
||||||
? _loadingHistory
|
? _loadingHistory
|
||||||
? Container(
|
? Container(
|
||||||
height: 50,
|
height: 50,
|
||||||
@ -512,7 +551,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
? Duration(milliseconds: 0)
|
? Duration(milliseconds: 0)
|
||||||
: Duration(milliseconds: 500),
|
: Duration(milliseconds: 500),
|
||||||
alignment:
|
alignment:
|
||||||
timeline.events.first.senderId ==
|
filteredEvents.first.senderId ==
|
||||||
client.userID
|
client.userID
|
||||||
? Alignment.topRight
|
? Alignment.topRight
|
||||||
: Alignment.topLeft,
|
: Alignment.topLeft,
|
||||||
@ -530,7 +569,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
bottom: 8,
|
bottom: 8,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Message(timeline.events[i - 1],
|
: Message(filteredEvents[i - 1],
|
||||||
onAvatarTab: (Event event) {
|
onAvatarTab: (Event event) {
|
||||||
sendController.text +=
|
sendController.text +=
|
||||||
' ${event.senderId}';
|
' ${event.senderId}';
|
||||||
@ -553,10 +592,10 @@ class _ChatState extends State<_Chat> {
|
|||||||
},
|
},
|
||||||
longPressSelect: selectedEvents.isEmpty,
|
longPressSelect: selectedEvents.isEmpty,
|
||||||
selected: selectedEvents
|
selected: selectedEvents
|
||||||
.contains(timeline.events[i - 1]),
|
.contains(filteredEvents[i - 1]),
|
||||||
timeline: timeline,
|
timeline: timeline,
|
||||||
nextEvent: i >= 2
|
nextEvent: i >= 2
|
||||||
? timeline.events[i - 2]
|
? filteredEvents[i - 2]
|
||||||
: null);
|
: null);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -565,17 +604,23 @@ class _ChatState extends State<_Chat> {
|
|||||||
ConnectionStatusHeader(),
|
ConnectionStatusHeader(),
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
height: replyEvent != null ? 56 : 0,
|
height: editEvent != null || replyEvent != null ? 56 : 0,
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Theme.of(context).secondaryHeaderColor,
|
color: Theme.of(context).secondaryHeaderColor,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.close),
|
icon: Icon(Icons.close),
|
||||||
onPressed: () => setState(() => replyEvent = null),
|
onPressed: () => setState(() {
|
||||||
|
replyEvent = null;
|
||||||
|
editEvent = null;
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ReplyContent(replyEvent),
|
child: replyEvent != null
|
||||||
|
? ReplyContent(replyEvent, timeline: timeline)
|
||||||
|
: _EditContent(
|
||||||
|
editEvent?.getDisplayEvent(timeline)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -611,7 +656,10 @@ class _ChatState extends State<_Chat> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
selectedEvents.length == 1
|
selectedEvents.length == 1
|
||||||
? selectedEvents.first.status > 0
|
? selectedEvents.first
|
||||||
|
.getDisplayEvent(timeline)
|
||||||
|
.status >
|
||||||
|
0
|
||||||
? Container(
|
? Container(
|
||||||
height: 56,
|
height: 56,
|
||||||
child: FlatButton(
|
child: FlatButton(
|
||||||
@ -629,7 +677,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
height: 56,
|
height: 56,
|
||||||
child: FlatButton(
|
child: FlatButton(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
sendAgainAction(),
|
sendAgainAction(timeline),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(L10n.of(context)
|
Text(L10n.of(context)
|
||||||
@ -804,3 +852,38 @@ class _ChatState extends State<_Chat> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _EditContent extends StatelessWidget {
|
||||||
|
final Event event;
|
||||||
|
|
||||||
|
_EditContent(this.event);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (event == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Icon(
|
||||||
|
Icons.edit,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
|
Container(width: 15.0),
|
||||||
|
Text(
|
||||||
|
event?.getLocalizedBody(
|
||||||
|
L10n.of(context),
|
||||||
|
withSenderNamePrefix: false,
|
||||||
|
hideReply: true,
|
||||||
|
) ??
|
||||||
|
'',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).textTheme.bodyText2.color,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
262
pubspec.lock
262
pubspec.lock
@ -14,7 +14,14 @@ packages:
|
|||||||
name: analyzer
|
name: analyzer
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.39.15"
|
version: "0.39.16"
|
||||||
|
ansicolor:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ansicolor
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -35,14 +42,14 @@ packages:
|
|||||||
name: asn1lib
|
name: asn1lib
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.4"
|
version: "0.6.5"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.2"
|
||||||
base58check:
|
base58check:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -63,7 +70,7 @@ packages:
|
|||||||
name: bot_toast
|
name: bot_toast
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.1"
|
||||||
bubble:
|
bubble:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -78,6 +85,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
characters:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: characters
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -105,7 +119,7 @@ packages:
|
|||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.14.12"
|
version: "1.14.13"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -119,21 +133,21 @@ packages:
|
|||||||
name: coverage
|
name: coverage
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.6"
|
version: "0.14.0"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.5"
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: csslib
|
name: csslib
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.16.1"
|
version: "0.16.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -147,7 +161,7 @@ packages:
|
|||||||
name: dart_style
|
name: dart_style
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.6"
|
||||||
encrypt:
|
encrypt:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -155,12 +169,19 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
|
fake_async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fake_async
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
famedlysdk:
|
famedlysdk:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "3fae58439bdc2100d26fbfb92a62c7fbb7b48903"
|
ref: "574fe27101bb03c8c18c776e98f7f44668e6d159"
|
||||||
resolved-ref: "3fae58439bdc2100d26fbfb92a62c7fbb7b48903"
|
resolved-ref: "574fe27101bb03c8c18c776e98f7f44668e6d159"
|
||||||
url: "https://gitlab.com/famedly/famedlysdk.git"
|
url: "https://gitlab.com/famedly/famedlysdk.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
@ -171,27 +192,34 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.3"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.1"
|
||||||
file_picker:
|
file_picker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.12.0"
|
version: "1.13.2"
|
||||||
file_picker_platform_interface:
|
file_picker_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file_picker_platform_interface
|
name: file_picker_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.1"
|
||||||
firebase_messaging:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.13"
|
version: "6.0.16"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -200,31 +228,33 @@ packages:
|
|||||||
flutter_advanced_networkimage:
|
flutter_advanced_networkimage:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_advanced_networkimage
|
path: "."
|
||||||
url: "https://pub.dartlang.org"
|
ref: master
|
||||||
source: hosted
|
resolved-ref: f0f599fb89c494d9158fb6f13d4870582f8ecfcb
|
||||||
version: "0.6.4"
|
url: "https://github.com/mchome/flutter_advanced_networkimage"
|
||||||
|
source: git
|
||||||
|
version: "0.8.0"
|
||||||
flutter_keyboard_visibility:
|
flutter_keyboard_visibility:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_keyboard_visibility
|
name: flutter_keyboard_visibility
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.0"
|
version: "3.2.1"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.4"
|
version: "0.7.5"
|
||||||
flutter_local_notifications:
|
flutter_local_notifications:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_local_notifications
|
name: flutter_local_notifications
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.3"
|
version: "1.4.4+2"
|
||||||
flutter_local_notifications_platform_interface:
|
flutter_local_notifications_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -240,9 +270,11 @@ packages:
|
|||||||
flutter_matrix_html:
|
flutter_matrix_html:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_matrix_html
|
path: "."
|
||||||
url: "https://pub.dartlang.org"
|
ref: "530df434b50002e04cbad63f53d6f0f5d5adbab5"
|
||||||
source: hosted
|
resolved-ref: "530df434b50002e04cbad63f53d6f0f5d5adbab5"
|
||||||
|
url: "https://github.com/Sorunome/flutter_matrix_html"
|
||||||
|
source: git
|
||||||
version: "0.1.2"
|
version: "0.1.2"
|
||||||
flutter_olm:
|
flutter_olm:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
@ -264,14 +296,14 @@ packages:
|
|||||||
name: flutter_secure_storage
|
name: flutter_secure_storage
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.1+1"
|
version: "3.3.3"
|
||||||
flutter_slidable:
|
flutter_slidable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_slidable
|
name: flutter_slidable
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.4"
|
version: "0.5.5"
|
||||||
flutter_sound:
|
flutter_sound:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -285,7 +317,7 @@ packages:
|
|||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.4"
|
version: "0.18.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -297,7 +329,7 @@ packages:
|
|||||||
name: flutter_typeahead
|
name: flutter_typeahead
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.7"
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -330,7 +362,7 @@ packages:
|
|||||||
name: http
|
name: http
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.1"
|
version: "0.12.2"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -344,21 +376,21 @@ packages:
|
|||||||
name: http_parser
|
name: http_parser
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "3.1.4"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image
|
name: image
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.12"
|
version: "2.1.14"
|
||||||
image_picker:
|
image_picker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image_picker
|
name: image_picker
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.7+2"
|
version: "0.6.7+4"
|
||||||
image_picker_platform_interface:
|
image_picker_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -379,35 +411,35 @@ packages:
|
|||||||
name: intl_translation
|
name: intl_translation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.9"
|
version: "0.17.10"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: io
|
name: io
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.3"
|
version: "0.3.4"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1+1"
|
version: "0.6.2"
|
||||||
link_text:
|
link_text:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: link_text
|
name: link_text
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.1"
|
version: "0.1.2"
|
||||||
localstorage:
|
localstorage:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: localstorage
|
name: localstorage
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1+4"
|
version: "3.0.2+5"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -421,14 +453,14 @@ packages:
|
|||||||
name: markdown
|
name: markdown
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.7"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.6"
|
version: "0.12.8"
|
||||||
matrix_file_e2ee:
|
matrix_file_e2ee:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -463,14 +495,14 @@ packages:
|
|||||||
name: mime_type
|
name: mime_type
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.3.2"
|
||||||
moor:
|
moor:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: moor
|
name: moor
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.3.0"
|
||||||
moor_ffi:
|
moor_ffi:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -478,34 +510,27 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.5.0"
|
||||||
multi_server_socket:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: multi_server_socket
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.2"
|
|
||||||
node_interop:
|
node_interop:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: node_interop
|
name: node_interop
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.1.1"
|
||||||
node_io:
|
node_io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: node_io
|
name: node_io
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1+2"
|
version: "1.1.1"
|
||||||
node_preamble:
|
node_preamble:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: node_preamble
|
name: node_preamble
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.8"
|
version: "1.4.12"
|
||||||
olm:
|
olm:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -527,13 +552,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.3"
|
version: "1.9.3"
|
||||||
package_resolver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: package_resolver
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.10"
|
|
||||||
password_hash:
|
password_hash:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -547,7 +565,7 @@ packages:
|
|||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.4"
|
version: "1.7.0"
|
||||||
path_drawing:
|
path_drawing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -568,7 +586,28 @@ packages:
|
|||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.6.11"
|
||||||
|
path_provider_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1+2"
|
||||||
|
path_provider_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.4+3"
|
||||||
|
path_provider_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -582,7 +621,7 @@ packages:
|
|||||||
name: petitparser
|
name: petitparser
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "3.0.4"
|
||||||
photo_view:
|
photo_view:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -597,6 +636,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
|
platform_detect:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: platform_detect
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -618,55 +664,55 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
|
process:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: process
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.13"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pub_semver
|
name: pub_semver
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.2"
|
version: "1.4.4"
|
||||||
quiver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: quiver
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.3"
|
|
||||||
random_string:
|
random_string:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: random_string
|
name: random_string
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.1.0"
|
||||||
receive_sharing_intent:
|
receive_sharing_intent:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: receive_sharing_intent
|
name: receive_sharing_intent
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.4.0+2"
|
||||||
share:
|
share:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: share
|
name: share
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.3+5"
|
version: "0.6.4+3"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.5"
|
version: "0.7.7"
|
||||||
shelf_packages_handler:
|
shelf_packages_handler:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_packages_handler
|
name: shelf_packages_handler
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.0"
|
||||||
shelf_static:
|
shelf_static:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -713,14 +759,28 @@ packages:
|
|||||||
name: sqflite
|
name: sqflite
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.1"
|
||||||
|
sqflite_common:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqflite_common
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2+1"
|
||||||
|
sqlite3:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqlite3
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.4"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.3"
|
version: "1.9.5"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -741,7 +801,7 @@ packages:
|
|||||||
name: synchronized
|
name: synchronized
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.2.0+2"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -755,28 +815,28 @@ packages:
|
|||||||
name: test
|
name: test
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.14.4"
|
version: "1.15.2"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.15"
|
version: "0.2.17"
|
||||||
test_core:
|
test_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_core
|
name: test_core
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.4"
|
version: "0.3.10"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.6"
|
version: "1.2.0"
|
||||||
universal_html:
|
universal_html:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -790,7 +850,7 @@ packages:
|
|||||||
name: universal_io
|
name: universal_io
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.6"
|
version: "1.0.1"
|
||||||
unorm_dart:
|
unorm_dart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -804,28 +864,35 @@ packages:
|
|||||||
name: url_launcher
|
name: url_launcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.4.1"
|
version: "5.5.0"
|
||||||
|
url_launcher_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: url_launcher_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1+1"
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_macos
|
name: url_launcher_macos
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.1+2"
|
version: "0.0.1+7"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_platform_interface
|
name: url_launcher_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.7"
|
||||||
url_launcher_web:
|
url_launcher_web:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.0+2"
|
version: "0.1.2"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -839,14 +906,14 @@ packages:
|
|||||||
name: vm_service
|
name: vm_service
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "4.2.0"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: watcher
|
name: watcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.7+13"
|
version: "0.9.7+15"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -860,28 +927,35 @@ packages:
|
|||||||
name: webkit_inspection_protocol
|
name: webkit_inspection_protocol
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.3"
|
version: "0.7.3"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: webview_flutter
|
name: webview_flutter
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.19+9"
|
version: "0.3.22+1"
|
||||||
|
xdg_directories:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xdg_directories
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.1"
|
version: "4.2.0"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.1"
|
||||||
zone_local:
|
zone_local:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -890,5 +964,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2"
|
version: "0.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.7.0 <3.0.0"
|
dart: ">=2.9.0-14.0.dev <3.0.0"
|
||||||
flutter: ">=1.12.13+hotfix.5 <2.0.0"
|
flutter: ">=1.18.0-6.0.pre <2.0.0"
|
||||||
|
12
pubspec.yaml
12
pubspec.yaml
@ -27,14 +27,17 @@ dependencies:
|
|||||||
famedlysdk:
|
famedlysdk:
|
||||||
git:
|
git:
|
||||||
url: https://gitlab.com/famedly/famedlysdk.git
|
url: https://gitlab.com/famedly/famedlysdk.git
|
||||||
ref: 3fae58439bdc2100d26fbfb92a62c7fbb7b48903
|
ref: 574fe27101bb03c8c18c776e98f7f44668e6d159
|
||||||
|
|
||||||
localstorage: ^3.0.1+4
|
localstorage: ^3.0.1+4
|
||||||
bubble: ^1.1.9+1
|
bubble: ^1.1.9+1
|
||||||
memoryfilepicker: ^0.1.1
|
memoryfilepicker: ^0.1.1
|
||||||
url_launcher: ^5.4.1
|
url_launcher: ^5.4.1
|
||||||
url_launcher_web: ^0.1.0
|
url_launcher_web: ^0.1.0
|
||||||
flutter_advanced_networkimage: any
|
flutter_advanced_networkimage:
|
||||||
|
git:
|
||||||
|
url: https://github.com/mchome/flutter_advanced_networkimage
|
||||||
|
ref: master
|
||||||
firebase_messaging: ^6.0.13
|
firebase_messaging: ^6.0.13
|
||||||
flutter_local_notifications: ^1.4.3
|
flutter_local_notifications: ^1.4.3
|
||||||
link_text: ^0.1.1
|
link_text: ^0.1.1
|
||||||
@ -51,7 +54,10 @@ dependencies:
|
|||||||
open_file: ^3.0.1
|
open_file: ^3.0.1
|
||||||
mime_type: ^0.3.0
|
mime_type: ^0.3.0
|
||||||
bot_toast: ^3.0.0
|
bot_toast: ^3.0.0
|
||||||
flutter_matrix_html: ^0.1.2
|
flutter_matrix_html:
|
||||||
|
git:
|
||||||
|
url: https://github.com/Sorunome/flutter_matrix_html
|
||||||
|
ref: 530df434b50002e04cbad63f53d6f0f5d5adbab5
|
||||||
moor: ^3.0.2
|
moor: ^3.0.2
|
||||||
random_string: ^2.0.1
|
random_string: ^2.0.1
|
||||||
flutter_typeahead: ^1.8.1
|
flutter_typeahead: ^1.8.1
|
||||||
|
Loading…
Reference in New Issue
Block a user