Compare commits
1 commit
main
...
krille/pol
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c7bc747d2 |
11 changed files with 433 additions and 33 deletions
|
|
@ -2821,5 +2821,27 @@
|
|||
"invalidUrl": "Invalid url",
|
||||
"addLink": "Add link",
|
||||
"unableToJoinChat": "Unable to join chat. Maybe the other party has already closed the conversation.",
|
||||
"previous": "Previous"
|
||||
"previous": "Previous",
|
||||
"poll": "Poll",
|
||||
"question": "Question",
|
||||
"answer": "Answer",
|
||||
"resultsDisclosed": "Results disclosed",
|
||||
"resultsUndisclosed": "Results undisclosed",
|
||||
"addAnswer": "Add answer",
|
||||
"deleteAnswer": "Delete answer",
|
||||
"startedAPoll": "{sender} started a poll",
|
||||
"@startedAPoll": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"sender": {}
|
||||
}
|
||||
},
|
||||
"countVotes": "{votes, plural, =1{1 vote} other{{votes} votes}} - {percentage}%",
|
||||
"@countVotes": {
|
||||
"type": "integer",
|
||||
"placeholders": {
|
||||
"votes": {},
|
||||
"percentage": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|||
import 'package:go_router/go_router.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/msc_extensions/msc_3381_polls/models/poll_event_content.dart';
|
||||
import 'package:matrix/msc_extensions/msc_3381_polls/poll_room_extension.dart';
|
||||
import 'package:record/record.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
|
@ -21,10 +23,13 @@ import 'package:universal_html/html.dart' as html;
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/setting_keys.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pages/chat/chat_input_row.dart';
|
||||
import 'package:fluffychat/pages/chat/chat_view.dart';
|
||||
import 'package:fluffychat/pages/chat/event_info_dialog.dart';
|
||||
import 'package:fluffychat/pages/chat/poll_edit_bottom_sheet.dart';
|
||||
import 'package:fluffychat/pages/chat/recording_dialog.dart';
|
||||
import 'package:fluffychat/pages/chat_details/chat_details.dart';
|
||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/utils/error_reporter.dart';
|
||||
import 'package:fluffychat/utils/file_selector.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
||||
|
|
@ -1117,24 +1122,44 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
FocusScope.of(context).requestFocus(inputFocus);
|
||||
}
|
||||
|
||||
void onAddPopupMenuButtonSelected(String choice) {
|
||||
if (choice == 'file') {
|
||||
sendFileAction();
|
||||
}
|
||||
if (choice == 'image') {
|
||||
sendImageAction();
|
||||
}
|
||||
if (choice == 'camera') {
|
||||
openCameraAction();
|
||||
}
|
||||
if (choice == 'camera-video') {
|
||||
openVideoCameraAction();
|
||||
}
|
||||
if (choice == 'location') {
|
||||
sendLocationAction();
|
||||
void onAddPopupMenuButtonSelected(AttachmentButtonAction choice) {
|
||||
switch (choice) {
|
||||
case AttachmentButtonAction.file:
|
||||
sendFileAction();
|
||||
break;
|
||||
case AttachmentButtonAction.image:
|
||||
sendImageAction();
|
||||
break;
|
||||
case AttachmentButtonAction.camera:
|
||||
openCameraAction();
|
||||
break;
|
||||
case AttachmentButtonAction.video:
|
||||
openVideoCameraAction();
|
||||
break;
|
||||
case AttachmentButtonAction.location:
|
||||
sendLocationAction();
|
||||
break;
|
||||
case AttachmentButtonAction.poll:
|
||||
sendPollAction();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sendPollAction() async {
|
||||
final poll = await showAdaptiveBottomSheet<PollStartContent>(
|
||||
context: context,
|
||||
builder: (context) => const PollEditBottomSheet(),
|
||||
);
|
||||
|
||||
if (poll == null) return;
|
||||
await room.startPoll(
|
||||
question: poll.question.mText,
|
||||
answers: poll.answers,
|
||||
maxSelections: poll.maxSelections,
|
||||
kind: poll.kind ?? PollKind.undisclosed,
|
||||
);
|
||||
}
|
||||
|
||||
unpinEvent(String eventId) async {
|
||||
final response = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -102,13 +102,12 @@ class ChatInputRow extends StatelessWidget {
|
|||
alignment: Alignment.center,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: const BoxDecoration(),
|
||||
child: PopupMenuButton<String>(
|
||||
child: PopupMenuButton<AttachmentButtonAction>(
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
onSelected: controller.onAddPopupMenuButtonSelected,
|
||||
itemBuilder: (BuildContext context) =>
|
||||
<PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'file',
|
||||
itemBuilder: (BuildContext context) => [
|
||||
PopupMenuItem(
|
||||
value: AttachmentButtonAction.file,
|
||||
child: ListTile(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.green,
|
||||
|
|
@ -119,8 +118,8 @@ class ChatInputRow extends StatelessWidget {
|
|||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'image',
|
||||
PopupMenuItem(
|
||||
value: AttachmentButtonAction.image,
|
||||
child: ListTile(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.blue,
|
||||
|
|
@ -132,8 +131,8 @@ class ChatInputRow extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
PopupMenuItem<String>(
|
||||
value: 'camera',
|
||||
PopupMenuItem(
|
||||
value: AttachmentButtonAction.camera,
|
||||
child: ListTile(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.purple,
|
||||
|
|
@ -145,8 +144,8 @@ class ChatInputRow extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
PopupMenuItem<String>(
|
||||
value: 'camera-video',
|
||||
PopupMenuItem(
|
||||
value: AttachmentButtonAction.video,
|
||||
child: ListTile(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.red,
|
||||
|
|
@ -158,8 +157,8 @@ class ChatInputRow extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
PopupMenuItem<String>(
|
||||
value: 'location',
|
||||
PopupMenuItem(
|
||||
value: AttachmentButtonAction.location,
|
||||
child: ListTile(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.brown,
|
||||
|
|
@ -170,6 +169,18 @@ class ChatInputRow extends StatelessWidget {
|
|||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: AttachmentButtonAction.poll,
|
||||
child: ListTile(
|
||||
leading: const CircleAvatar(
|
||||
backgroundColor: Colors.deepOrange,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.ballot_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context).poll),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -309,7 +320,7 @@ class _ChatAccountPicker extends StatelessWidget {
|
|||
onSelected: (mxid) => _popupMenuButtonSelected(mxid, context),
|
||||
itemBuilder: (BuildContext context) => clients
|
||||
.map(
|
||||
(client) => PopupMenuItem<String>(
|
||||
(client) => PopupMenuItem(
|
||||
value: client!.userID,
|
||||
child: FutureBuilder<Profile>(
|
||||
future: client.fetchOwnProfile(),
|
||||
|
|
@ -338,3 +349,5 @@ class _ChatAccountPicker extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum AttachmentButtonAction { file, image, camera, video, location, poll }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
|
|||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix/msc_extensions/msc_3381_polls/models/poll_event_content.dart';
|
||||
import 'package:swipe_to_action/swipe_to_action.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
|
|
@ -66,6 +67,7 @@ class Message extends StatelessWidget {
|
|||
EventTypes.Sticker,
|
||||
EventTypes.Encrypted,
|
||||
EventTypes.CallInvite,
|
||||
PollEventContent.startType,
|
||||
}.contains(event.type)) {
|
||||
if (event.type.startsWith('m.call.')) {
|
||||
return const SizedBox.shrink();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:fluffychat/pages/chat/events/poll_event.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
|
@ -12,6 +13,7 @@ import 'package:fluffychat/utils/date_time_extension.dart';
|
|||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:matrix/msc_extensions/msc_3381_polls/models/poll_event_content.dart';
|
||||
import '../../../config/app_config.dart';
|
||||
import '../../../utils/platform_infos.dart';
|
||||
import '../../../utils/url_launcher.dart';
|
||||
|
|
@ -292,6 +294,8 @@ class MessageContent extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
);
|
||||
case PollEventContent.startType:
|
||||
return PollEvent(event, textColor: textColor, timeline: timeline);
|
||||
default:
|
||||
return FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
|
|
|
|||
106
lib/pages/chat/events/poll_event.dart
Normal file
106
lib/pages/chat/events/poll_event.dart
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/msc_extensions/msc_3381_polls/poll_event_extension.dart';
|
||||
|
||||
class PollEvent extends StatelessWidget {
|
||||
final Event event;
|
||||
final Timeline timeline;
|
||||
final Color textColor;
|
||||
const PollEvent(
|
||||
this.event, {
|
||||
required this.textColor,
|
||||
required this.timeline,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
|
||||
final content = event.parsedPollEventContent.pollStartContent;
|
||||
final answers = event.getPollResponses(timeline);
|
||||
final answersLength = answers.length;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
content.question.mText,
|
||||
style: TextStyle(color: textColor, fontSize: fontSize),
|
||||
),
|
||||
for (final answer in content.answers)
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final votes =
|
||||
answers.values.where((v) => v.contains(answer.id)).length;
|
||||
final percentage = answersLength == 0 ? 0 : votes / answersLength;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 4,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 32,
|
||||
child: Material(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
final ownAnswers =
|
||||
answers[event.room.client.userID] ?? {};
|
||||
if (ownAnswers.contains(answer.id)) {
|
||||
ownAnswers.remove(answer.id);
|
||||
} else {
|
||||
ownAnswers.add(answer.id);
|
||||
}
|
||||
showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => event.answerPoll(ownAnswers.toList()),
|
||||
);
|
||||
},
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
child: Stack(
|
||||
children: [
|
||||
LinearProgressIndicator(
|
||||
minHeight: 32,
|
||||
backgroundColor: textColor.withAlpha(16),
|
||||
color: textColor.withAlpha(64),
|
||||
value: percentage.toDouble(),
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
Center(
|
||||
child: Text(
|
||||
answer.mText,
|
||||
style: TextStyle(color: textColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (answersLength > 0)
|
||||
Text(
|
||||
L10n.of(context).countVotes(
|
||||
votes,
|
||||
(percentage * 100).round(),
|
||||
),
|
||||
style: theme.textTheme.labelSmall
|
||||
?.copyWith(color: textColor),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
222
lib/pages/chat/poll_edit_bottom_sheet.dart
Normal file
222
lib/pages/chat/poll_edit_bottom_sheet.dart
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/msc_extensions/msc_3381_polls/models/poll_event_content.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
|
||||
class PollEditBottomSheet extends StatefulWidget {
|
||||
final PollStartContent? oldPoll;
|
||||
const PollEditBottomSheet({this.oldPoll, super.key});
|
||||
|
||||
@override
|
||||
State<PollEditBottomSheet> createState() => _PollEditBottomSheetState();
|
||||
}
|
||||
|
||||
class _PollEditBottomSheetState extends State<PollEditBottomSheet> {
|
||||
final TextEditingController _questionController = TextEditingController();
|
||||
final List<TextEditingController> _answerController = [
|
||||
TextEditingController(),
|
||||
TextEditingController(),
|
||||
];
|
||||
PollKind _kind = PollKind.disclosed;
|
||||
int _maxSelection = 1;
|
||||
|
||||
bool _canFinish = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final oldPoll = widget.oldPoll;
|
||||
if (oldPoll != null) {
|
||||
_questionController.text = oldPoll.question.mText;
|
||||
_answerController.clear();
|
||||
_answerController.addAll(
|
||||
oldPoll.answers.map(
|
||||
(answer) => TextEditingController(text: answer.mText),
|
||||
),
|
||||
);
|
||||
_kind = oldPoll.kind ?? _kind;
|
||||
_maxSelection = oldPoll.maxSelections;
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _checkCanFinish([_]) {
|
||||
final canFinish = _questionController.text.isNotEmpty &&
|
||||
_answerController.length >= 2 &&
|
||||
!_answerController.any((c) => c.text.isEmpty);
|
||||
if (canFinish != _canFinish) {
|
||||
setState(() {
|
||||
_canFinish = canFinish;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _deleteAnswer(int i) {
|
||||
setState(() {
|
||||
_answerController.removeAt(i);
|
||||
if (_maxSelection > _answerController.length) _maxSelection--;
|
||||
});
|
||||
_checkCanFinish();
|
||||
}
|
||||
|
||||
void _addAnswer() {
|
||||
setState(() {
|
||||
_answerController.add(TextEditingController());
|
||||
});
|
||||
}
|
||||
|
||||
void _updateMaxSelection(int? maxSelection) {
|
||||
if (maxSelection == null) return;
|
||||
setState(() {
|
||||
_maxSelection = maxSelection;
|
||||
});
|
||||
}
|
||||
|
||||
void _updateKind(PollKind? kind) {
|
||||
if (kind == null) return;
|
||||
setState(() {
|
||||
_kind = kind;
|
||||
});
|
||||
}
|
||||
|
||||
void _finish() {
|
||||
_checkCanFinish();
|
||||
context.pop(
|
||||
PollStartContent(
|
||||
maxSelections: _maxSelection,
|
||||
question: PollQuestion(
|
||||
mText: _questionController.text,
|
||||
),
|
||||
kind: _kind,
|
||||
answers: _answerController
|
||||
.map((c) => c.text)
|
||||
.where((text) => text.isNotEmpty)
|
||||
.mapIndexed(
|
||||
(i, text) => PollAnswer(
|
||||
mText: text,
|
||||
id: '$i$text'.hashCode.toString(),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: CloseButton(
|
||||
onPressed: () => context.pop(null),
|
||||
),
|
||||
title: Text(L10n.of(context).poll),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 12.0),
|
||||
child: ElevatedButton(
|
||||
onPressed: _canFinish ? _finish : null,
|
||||
child: Text(L10n.of(context).send),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
TextField(
|
||||
controller: _questionController,
|
||||
minLines: 1,
|
||||
maxLines: 4,
|
||||
maxLength: 1024,
|
||||
onChanged: _checkCanFinish,
|
||||
decoration: InputDecoration(
|
||||
counterText: '',
|
||||
labelText: L10n.of(context).question,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
for (var i = 0; i < _answerController.length; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16.0),
|
||||
child: TextField(
|
||||
controller: _answerController[i],
|
||||
maxLength: 128,
|
||||
onChanged: _checkCanFinish,
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).answer,
|
||||
counterText: '',
|
||||
suffixIcon: i > 1
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
tooltip: L10n.of(context).deleteAnswer,
|
||||
onPressed: () => _deleteAnswer(i),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: TextButton.icon(
|
||||
onPressed: () => _addAnswer(),
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
label: Text(L10n.of(context).addAnswer),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
Wrap(
|
||||
children: [
|
||||
DropdownButton<PollKind>(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||
underline: const SizedBox.shrink(),
|
||||
value: _kind,
|
||||
items: PollKind.values
|
||||
.map(
|
||||
(kind) => DropdownMenuItem(
|
||||
value: kind,
|
||||
child: Text(kind.getLocalizedString(context)),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: _updateKind,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
DropdownButton<int>(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||
underline: const SizedBox.shrink(),
|
||||
value: _maxSelection,
|
||||
items: [
|
||||
for (var i = 1; i <= _answerController.length; i++)
|
||||
DropdownMenuItem(
|
||||
value: i,
|
||||
child: Text('Max selection: $i'),
|
||||
),
|
||||
],
|
||||
onChanged: _updateMaxSelection,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension on PollKind {
|
||||
String getLocalizedString(BuildContext context) {
|
||||
switch (this) {
|
||||
case PollKind.disclosed:
|
||||
return L10n.of(context).resultsDisclosed;
|
||||
case PollKind.undisclosed:
|
||||
return L10n.of(context).resultsUndisclosed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,5 +59,6 @@ extension IsStateExtension on Event {
|
|||
EventTypes.Message,
|
||||
EventTypes.Sticker,
|
||||
EventTypes.Encrypted,
|
||||
'org.matrix.msc3381.poll.start',
|
||||
}.contains(type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,4 +350,7 @@ class MatrixLocals extends MatrixLocalizations {
|
|||
|
||||
@override
|
||||
String get cancelledSend => l10n.sendCanceled;
|
||||
|
||||
@override
|
||||
String startedAPoll(String senderName) => l10n.startedAPoll(senderName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1158,8 +1158,8 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "928f6ba96f259ab586ccfeb6c1674aa61ea6d16a"
|
||||
ref: "krille/implement-polls-msc"
|
||||
resolved-ref: "2d08d24c87c3baa02e6a73e58d790df29a8546fd"
|
||||
url: "https://github.com/famedly/matrix-dart-sdk.git"
|
||||
source: git
|
||||
version: "0.36.0"
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@ dependencies:
|
|||
latlong2: ^0.9.1
|
||||
linkify: ^5.0.0
|
||||
matrix:
|
||||
git: https://github.com/famedly/matrix-dart-sdk.git
|
||||
git:
|
||||
url: https://github.com/famedly/matrix-dart-sdk.git
|
||||
ref: krille/implement-polls-msc
|
||||
mime: ^1.0.6
|
||||
native_imaging: ^0.1.1
|
||||
opus_caf_converter_dart: ^1.0.1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue