Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core, ui, localization): Add Poll attachment composer #2048

Merged
merged 31 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
10968f1
feat: add support for polls api
xsahil03x Oct 25, 2024
678806a
chore: fix analysis
xsahil03x Oct 25, 2024
9468141
Merge branch 'master' into feat/message-polls-apis
deven98 Oct 25, 2024
08029a2
test: fix test
xsahil03x Oct 25, 2024
a9261b9
Merge remote-tracking branch 'origin/feat/message-polls-apis' into fe…
xsahil03x Oct 25, 2024
cd26fbc
revert: revert state changes
xsahil03x Oct 25, 2024
921086d
test: fix test
xsahil03x Oct 25, 2024
33c5a75
chore: fix lints
xsahil03x Oct 25, 2024
b5d3fe5
chore: improve cast poll vote api
xsahil03x Oct 28, 2024
2d429da
feat: add poll event handlers
xsahil03x Oct 29, 2024
4d68b56
Add Poll attachment composer
xsahil03x Nov 11, 2024
06e6be1
add poll creator theme appBarElevation
xsahil03x Nov 12, 2024
d00b542
Add poll creator widget tests
xsahil03x Nov 12, 2024
818f10b
add StreamPollController test
xsahil03x Nov 12, 2024
a5fd7f6
add translations for poll creator
xsahil03x Nov 12, 2024
8329d53
feat: add support for polls api
xsahil03x Oct 25, 2024
4653c7a
chore: fix analysis
xsahil03x Oct 25, 2024
b5893cf
test: fix test
xsahil03x Oct 25, 2024
c3cc1d7
revert: revert state changes
xsahil03x Oct 25, 2024
a6fd19b
test: fix test
xsahil03x Oct 25, 2024
9a8626f
chore: fix lints
xsahil03x Oct 25, 2024
8fd289a
chore: improve cast poll vote api
xsahil03x Oct 28, 2024
f9e7664
feat: add poll event handlers
xsahil03x Oct 29, 2024
822ca86
Merge remote-tracking branch 'origin/feat/message-polls-apis' into fe…
xsahil03x Dec 9, 2024
30cde86
Merge remote-tracking branch 'origin/master' into feat/polls-attachme…
xsahil03x Dec 10, 2024
582db22
chore: fix lints and tests
xsahil03x Dec 10, 2024
0295672
chore: update CHANGELOG.md
xsahil03x Dec 10, 2024
124d4f8
chore: update CHANGELOG.md
xsahil03x Dec 10, 2024
e84999a
chore: fix lint
xsahil03x Dec 10, 2024
909bc6e
test: update tests
xsahil03x Dec 10, 2024
395d6ec
fix: use translated poll picker title
xsahil03x Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,36 @@
return _client.sendEvent(id!, type, event);
}

/// Send a message with a poll to this channel.
///
/// Optionally provide a [messageText] to send a message along with the poll.
Future<SendMessageResponse> sendPoll(

Check warning on line 1041 in packages/stream_chat/lib/src/client/channel.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/client/channel.dart#L1041

Added line #L1041 was not covered by tests
Poll poll, {
String messageText = '',
}) async {
_checkInitialized();
final res = await _client.createPoll(poll);
return sendMessage(
Message(

Check warning on line 1048 in packages/stream_chat/lib/src/client/channel.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/client/channel.dart#L1045-L1048

Added lines #L1045 - L1048 were not covered by tests
text: messageText,
poll: res.poll,
pollId: res.poll.id,

Check warning on line 1051 in packages/stream_chat/lib/src/client/channel.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/client/channel.dart#L1050-L1051

Added lines #L1050 - L1051 were not covered by tests
),
);
}

/// Updates the [poll] in this channel.
Future<UpdatePollResponse> updatePoll(Poll poll) {
_checkInitialized();
return _client.updatePoll(poll);

Check warning on line 1059 in packages/stream_chat/lib/src/client/channel.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/client/channel.dart#L1057-L1059

Added lines #L1057 - L1059 were not covered by tests
}

/// Deletes the poll with the given [pollId] from this channel.
Future<EmptyResponse> deletePoll(String pollId) {
_checkInitialized();
return _client.deletePoll(pollId);

Check warning on line 1065 in packages/stream_chat/lib/src/client/channel.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/client/channel.dart#L1063-L1065

Added lines #L1063 - L1065 were not covered by tests
}

/// Send a reaction to this channel.
///
/// Set [enforceUnique] to true to remove the existing user reaction.
Expand Down
14 changes: 11 additions & 3 deletions packages/stream_chat/lib/src/core/models/poll.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

part 'poll.g.dart';

class _NullConst {
const _NullConst();
}

const _nullConst = _NullConst();

/// {@template streamVotingVisibility}
/// Represents the visibility of the voting process.
/// {@endtemplate}
Expand All @@ -32,7 +38,7 @@
this.description,
required this.options,
this.votingVisibility = VotingVisibility.public,
this.enforceUniqueVote = false,
this.enforceUniqueVote = true,
this.maxVotesAllowed,
this.allowAnswers = false,
this.answers = const [],
Expand Down Expand Up @@ -159,7 +165,7 @@
List<PollOption>? options,
VotingVisibility? votingVisibility,
bool? enforceUniqueVote,
int? maxVotesAllowed,
Object? maxVotesAllowed = _nullConst,
bool? allowUserSuggestedOptions,
bool? allowAnswers,
bool? isClosed,
Expand All @@ -182,7 +188,9 @@
options: options ?? this.options,
votingVisibility: votingVisibility ?? this.votingVisibility,
enforceUniqueVote: enforceUniqueVote ?? this.enforceUniqueVote,
maxVotesAllowed: maxVotesAllowed ?? this.maxVotesAllowed,
maxVotesAllowed: maxVotesAllowed == _nullConst
? this.maxVotesAllowed

Check warning on line 192 in packages/stream_chat/lib/src/core/models/poll.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/core/models/poll.dart#L191-L192

Added lines #L191 - L192 were not covered by tests
: maxVotesAllowed as int?,
allowUserSuggestedOptions:
allowUserSuggestedOptions ?? this.allowUserSuggestedOptions,
allowAnswers: allowAnswers ?? this.allowAnswers,
Expand Down
2 changes: 1 addition & 1 deletion packages/stream_chat/lib/src/core/models/poll.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion packages/stream_chat/lib/src/core/models/poll_option.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

part 'poll_option.g.dart';

class _NullConst {
const _NullConst();
}

const _nullConst = _NullConst();

/// {@template streamPollOption}
/// A model class representing a poll option.
/// {@endtemplate}
Expand All @@ -23,7 +29,7 @@
);

/// The unique identifier of the poll option.
@JsonKey(includeToJson: false)
@JsonKey(includeIfNull: false)
final String? id;

/// The text describing the poll option.
Expand All @@ -36,6 +42,18 @@
Map<String, dynamic> toJson() =>
Serializer.moveFromExtraDataToRoot(_$PollOptionToJson(this));

/// Creates a copy of [PollOption] with specified attributes overridden.
PollOption copyWith({

Check warning on line 46 in packages/stream_chat/lib/src/core/models/poll_option.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/core/models/poll_option.dart#L46

Added line #L46 was not covered by tests
Object? id = _nullConst,
String? text,
Map<String, Object?>? extraData,
}) =>
PollOption(
id: id == _nullConst ? this.id : id as String?,
text: text ?? this.text,
extraData: extraData ?? this.extraData,

Check warning on line 54 in packages/stream_chat/lib/src/core/models/poll_option.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/core/models/poll_option.dart#L51-L54

Added lines #L51 - L54 were not covered by tests
);

/// Known top level fields.
///
/// Useful for [Serializer] methods.
Expand Down
19 changes: 14 additions & 5 deletions packages/stream_chat/lib/src/core/models/poll_option.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/stream_chat/lib/src/core/models/poll_vote.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PollVote extends Equatable {
_$PollVoteFromJson(json);

/// The unique identifier of the poll vote.
@JsonKey(includeToJson: false)
@JsonKey(includeIfNull: false)
final String? id;

/// The unique identifier of the option selected in the poll.
Expand Down
1 change: 1 addition & 0 deletions packages/stream_chat/lib/src/core/models/poll_vote.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions packages/stream_chat/lib/src/db/chat_persistence_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,11 @@
final members = state.members;
final Iterable<Message>? messages;
if (CurrentPlatform.isWeb) {
messages = state.messages?.where((it) => !it.attachments.any(
(attachment) =>
attachment.uploadState != const UploadState.success(),
));
messages = state.messages?.where(
(it) => !it.attachments.any(
(it) => it.uploadState != const UploadState.success(),

Check warning on line 260 in packages/stream_chat/lib/src/db/chat_persistence_client.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/db/chat_persistence_client.dart#L258-L260

Added lines #L258 - L260 were not covered by tests
),
);
} else {
messages = state.messages;
}
Expand Down
3 changes: 3 additions & 0 deletions packages/stream_chat/lib/src/permission_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,7 @@ class PermissionType {
/// Capability required to update/edit channel members
/// Channel is not distinct and user has UpdateChannelMembers permission
static const String updateChannelMembers = 'update-channel-members';

/// Capability required to send a poll in a channel.
static const String sendPoll = 'send-poll';
}
7 changes: 5 additions & 2 deletions packages/stream_chat/test/src/core/models/poll_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ void main() {
expect(json['name'], 'test');
expect(json['description'], isNull);
expect(json['options'], [
{'text': 'option1 text'}
{
'id': 'option1',
'text': 'option1 text',
}
]);
expect(json['voting_visibility'], 'public');
expect(json['enforce_unique_vote'], false);
expect(json['enforce_unique_vote'], true);
expect(json['max_votes_allowed'], isNull);
expect(json['allow_user_suggested_options'], false);
expect(json['allow_answers'], false);
Expand Down
6 changes: 6 additions & 0 deletions packages/stream_chat_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Upcoming

✅ Added

- Added a new `StreamPollCreator` widget to facilitate poll creation within the chat interface.

## 8.3.0

✅ Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class StreamUnreadIndicator extends StatelessWidget {

@override
Widget build(BuildContext context) {
final theme = StreamChatTheme.of(context);
final client = StreamChat.of(context).client;
return IgnorePointer(
child: BetterStreamBuilder<int>(
Expand All @@ -25,31 +26,18 @@ class StreamUnreadIndicator extends StatelessWidget {
initialData: cid != null
? client.state.channels[cid]?.state?.unreadCount
: client.state.totalUnreadCount,
builder: (context, data) {
if (data == 0) {
return const Offstage();
}
return Material(
borderRadius: BorderRadius.circular(8),
color: StreamChatTheme.of(context)
.channelPreviewTheme
.unreadCounterColor,
child: Padding(
padding: const EdgeInsets.only(
left: 5,
right: 5,
top: 2,
bottom: 1,
),
child: Center(
child: Text(
'${data > 99 ? '99+' : data}',
style: const TextStyle(
fontSize: 11,
color: Colors.white,
),
),
),
builder: (context, unreadCount) {
if (unreadCount == 0) return const SizedBox.shrink();

return Badge(
textColor: Colors.white,
textStyle: theme.textTheme.footnoteBold,
backgroundColor: theme.channelPreviewTheme.unreadCounterColor,
label: Text(
switch (unreadCount) {
> 99 => '99+',
_ => '$unreadCount',
},
),
);
},
Expand Down
Loading
Loading