Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion lib/model/autocomplete.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ class ChannelLinkAutocompleteView extends AutocompleteView<ChannelLinkAutocomple
required PerAccountStore store,
required Narrow narrow,
}) {
return store.streams.values.sorted(_comparator(narrow: narrow));
return store.channels.values.sorted(_comparator(narrow: narrow));
}

/// Compare the channels the same way they would be sorted as
Expand Down
88 changes: 44 additions & 44 deletions lib/model/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ mixin ChannelStore on UserStore {
@protected
UserStore get userStore;

/// All known channels/streams, indexed by [ZulipStream.streamId].
/// All known channels, indexed by [ZulipStream.streamId].
///
/// The same [ZulipStream] objects also appear in [streamsByName].
/// The same [ZulipStream] objects also appear in [channelsByName].
///
/// For channels the self-user is subscribed to, the value is in fact
/// a [Subscription] object and also appears in [subscriptions].
Map<int, ZulipStream> get streams;
Map<int, ZulipStream> get channels;

/// All known channels/streams, indexed by [ZulipStream.name].
/// All known channels, indexed by [ZulipStream.name].
///
/// The same [ZulipStream] objects also appear in [streams].
/// The same [ZulipStream] objects also appear in [channels].
///
/// For channels the self-user is subscribed to, the value is in fact
/// a [Subscription] object and also appears in [subscriptions].
Map<String, ZulipStream> get streamsByName;
Map<String, ZulipStream> get channelsByName;

/// All the channels the self-user is subscribed to, indexed by
/// [Subscription.streamId], with subscription details.
///
/// The same [Subscription] objects are among the values in [streams]
/// and [streamsByName].
/// The same [Subscription] objects are among the values in [channels]
/// and [channelsByName].
Map<int, Subscription> get subscriptions;

/// All the channel folders, including archived ones, indexed by ID.
Expand Down Expand Up @@ -168,7 +168,7 @@ mixin ChannelStore on UserStore {
/// The channel folder of [channelId],
/// including the "PINNED" or "OTHER" pseudo-channels (e.g. for the inbox).
UiChannelFolder uiChannelFolder(int channelId) =>
switch (streams[channelId]) {
switch (channels[channelId]) {
Subscription(:final pinToTop) when pinToTop =>
UiChannelFolderPseudoPinned(),
ZulipStream(:final folderId) when folderId != null =>
Expand Down Expand Up @@ -377,10 +377,10 @@ mixin ProxyChannelStore on ChannelStore {
ChannelStore get channelStore;

@override
Map<int, ZulipStream> get streams => channelStore.streams;
Map<int, ZulipStream> get channels => channelStore.channels;

@override
Map<String, ZulipStream> get streamsByName => channelStore.streamsByName;
Map<String, ZulipStream> get channelsByName => channelStore.channelsByName;

@override
Map<int, Subscription> get subscriptions => channelStore.subscriptions;
Expand Down Expand Up @@ -422,9 +422,9 @@ class ChannelStoreImpl extends HasUserStore with ChannelStore {
final subscriptions = Map.fromEntries(initialSnapshot.subscriptions.map(
(subscription) => MapEntry(subscription.streamId, subscription)));

final streams = Map<int, ZulipStream>.of(subscriptions);
final channels = Map<int, ZulipStream>.of(subscriptions);
for (final stream in initialSnapshot.streams) {
streams.putIfAbsent(stream.streamId, () => stream);
channels.putIfAbsent(stream.streamId, () => stream);
}

final channelFolders = Map.fromEntries((initialSnapshot.channelFolders ?? [])
Expand All @@ -442,8 +442,8 @@ class ChannelStoreImpl extends HasUserStore with ChannelStore {

return ChannelStoreImpl._(
users: users,
streams: streams,
streamsByName: streams.map((_, stream) => MapEntry(stream.name, stream)),
channels: channels,
channelsByName: channels.map((_, channel) => MapEntry(channel.name, channel)),
subscriptions: subscriptions,
channelFolders: channelFolders,
topicVisibility: topicVisibility,
Expand All @@ -452,17 +452,17 @@ class ChannelStoreImpl extends HasUserStore with ChannelStore {

ChannelStoreImpl._({
required super.users,
required this.streams,
required this.streamsByName,
required this.channels,
required this.channelsByName,
required this.subscriptions,
required this.channelFolders,
required this.topicVisibility,
});

@override
final Map<int, ZulipStream> streams;
final Map<int, ZulipStream> channels;
@override
final Map<String, ZulipStream> streamsByName;
final Map<String, ZulipStream> channelsByName;
@override
final Map<int, Subscription> subscriptions;
@override
Expand Down Expand Up @@ -490,27 +490,27 @@ class ChannelStoreImpl extends HasUserStore with ChannelStore {
switch (event) {
case ChannelCreateEvent():
assert(event.streams.every((stream) =>
!streams.containsKey(stream.streamId)
&& !streamsByName.containsKey(stream.name)));
streams.addEntries(event.streams.map((stream) => MapEntry(stream.streamId, stream)));
streamsByName.addEntries(event.streams.map((stream) => MapEntry(stream.name, stream)));
!channels.containsKey(stream.streamId)
&& !channelsByName.containsKey(stream.name)));
channels.addEntries(event.streams.map((stream) => MapEntry(stream.streamId, stream)));
channelsByName.addEntries(event.streams.map((stream) => MapEntry(stream.name, stream)));
// (Don't touch `subscriptions`. If the user is subscribed to the stream,
// details will come in a later `subscription` event.)

case ChannelDeleteEvent():
for (final channelId in event.channelIds) {
final channel = streams.remove(channelId);
final channel = channels.remove(channelId);
if (channel == null) continue; // TODO(log)
assert(channelId == channel.streamId);
assert(identical(channel, streamsByName[channel.name]));
assert(identical(channel, channelsByName[channel.name]));
assert(subscriptions[channelId] == null
|| identical(subscriptions[channelId], channel));
streamsByName.remove(channel.name);
channelsByName.remove(channel.name);
subscriptions.remove(channelId);
}

case ChannelUpdateEvent():
final stream = streams[event.streamId];
final stream = channels[event.streamId];
if (stream == null) return; // TODO(log)
assert(stream.streamId == event.streamId);

Expand All @@ -532,10 +532,10 @@ class ChannelStoreImpl extends HasUserStore with ChannelStore {
case ChannelPropertyName.name:
final streamName = stream.name;
assert(streamName == event.name);
assert(identical(streams[stream.streamId], streamsByName[streamName]));
assert(identical(channels[stream.streamId], channelsByName[streamName]));
stream.name = event.value as String;
streamsByName.remove(streamName);
streamsByName[stream.name] = stream;
channelsByName.remove(streamName);
channelsByName[stream.name] = stream;
case ChannelPropertyName.isArchived:
stream.isArchived = event.value as bool;
case ChannelPropertyName.description:
Expand Down Expand Up @@ -572,35 +572,35 @@ class ChannelStoreImpl extends HasUserStore with ChannelStore {
switch (event) {
case SubscriptionAddEvent():
for (final subscription in event.subscriptions) {
assert(streams.containsKey(subscription.streamId));
assert(streams[subscription.streamId] is! Subscription);
assert(streamsByName.containsKey(subscription.name));
assert(streamsByName[subscription.name] is! Subscription);
assert(channels.containsKey(subscription.streamId));
assert(channels[subscription.streamId] is! Subscription);
assert(channelsByName.containsKey(subscription.name));
assert(channelsByName[subscription.name] is! Subscription);
assert(!subscriptions.containsKey(subscription.streamId));
streams[subscription.streamId] = subscription;
streamsByName[subscription.name] = subscription;
channels[subscription.streamId] = subscription;
channelsByName[subscription.name] = subscription;
subscriptions[subscription.streamId] = subscription;
}

case SubscriptionRemoveEvent():
for (final channelId in event.channelIds) {
assert(streams.containsKey(channelId));
assert(streams[channelId] is Subscription);
assert(streamsByName.containsKey(streams[channelId]!.name));
assert(streamsByName[streams[channelId]!.name] is Subscription);
assert(channels.containsKey(channelId));
assert(channels[channelId] is Subscription);
assert(channelsByName.containsKey(channels[channelId]!.name));
assert(channelsByName[channels[channelId]!.name] is Subscription);
assert(subscriptions.containsKey(channelId));
final subscription = subscriptions.remove(channelId);
if (subscription == null) continue; // TODO(log)
final stream = ZulipStream.fromSubscription(subscription);
streams[channelId] = stream;
streamsByName[subscription.name] = stream;
channels[channelId] = stream;
channelsByName[subscription.name] = stream;
}

case SubscriptionUpdateEvent():
final subscription = subscriptions[event.channelId];
if (subscription == null) return; // TODO(log)
assert(identical(streams[event.channelId], subscription));
assert(identical(streamsByName[subscription.name], subscription));
assert(identical(channels[event.channelId], subscription));
assert(identical(channelsByName[subscription.name], subscription));
switch (event.property) {
case SubscriptionProperty.color:
subscription.color = event.value as int;
Expand Down
8 changes: 4 additions & 4 deletions lib/model/internal_link.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ String narrowLinkFragment(PerAccountStore store, Narrow narrow, {int? nearMessag
switch (element) {
case ApiNarrowChannel():
final channelId = element.operand;
final name = store.streams[channelId]?.name ?? 'unknown';
final name = store.channels[channelId]?.name ?? 'unknown';
final slugifiedName = _encodeHashComponent(name.replaceAll(' ', '-'));
fragment.write('$channelId-$slugifiedName');
case ApiNarrowTopic():
Expand Down Expand Up @@ -380,16 +380,16 @@ int? _parseStreamOperand(String operand, ChannelStore store) {
// "New" (2018) format: ${stream_id}-${stream_name} .
final match = RegExp(r'^(\d+)(?:-.*)?$').firstMatch(operand);
final newFormatStreamId = (match != null) ? int.parse(match.group(1)!, radix: 10) : null;
if (newFormatStreamId != null && store.streams.containsKey(newFormatStreamId)) {
if (newFormatStreamId != null && store.channels.containsKey(newFormatStreamId)) {
return newFormatStreamId;
}

// Old format: just stream name. This case is relevant indefinitely,
// so that links in old conversations continue to work.
final String? streamName = decodeHashComponent(operand);
if (streamName == null) return null;
final stream = store.streamsByName[streamName];
if (stream != null) return stream.streamId;
final channel = store.channelsByName[streamName];
if (channel != null) return channel.streamId;

if (newFormatStreamId != null) {
// Neither format found a stream, so it's hidden or doesn't exist. But
Expand Down
2 changes: 1 addition & 1 deletion lib/model/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ mixin MessageStore on ChannelStore {

final ZulipStream? channel;
if (message is StreamMessage) {
channel = streams[message.streamId];
channel = channels[message.streamId];
if (channel == null) {
assert(false); // TODO(log)
return true;
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/action_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ void showChannelActionSheet(BuildContext context, {
&& messageListPageNarrow.channelId == channelId;

final unreadCount = store.unreads.countInChannelNarrow(channelId);
final channel = store.streams[channelId];
final channel = store.channels[channelId];
final isSubscribed = channel is Subscription;
final buttonSections = [
if (!isSubscribed
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ abstract final class ZulipAction {
required int channelId,
}) async {
final store = PerAccountStoreWidget.of(context);
final channel = store.streams[channelId];
final channel = store.channels[channelId];
if (channel == null || channel is Subscription) return; // TODO could give feedback

try {
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/all_channels.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AllChannelsPageBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
final zulipLocalizations = ZulipLocalizations.of(context);
final channels = PerAccountStoreWidget.of(context).streams;
final channels = PerAccountStoreWidget.of(context).channels;

if (channels.isEmpty) {
return PageBodyEmptyContentPlaceholder(
Expand Down
4 changes: 2 additions & 2 deletions lib/widgets/autocomplete.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class ComposeAutocomplete extends AutocompleteField<ComposeAutocompleteQuery, Co
// (maybe handle centrally in `controller`)
replacementString = '${userGroupMention(userGroup.name, silent: query.silent)} ';
case ChannelLinkAutocompleteResult(:final channelId):
final channel = store.streams[channelId];
final channel = store.channels[channelId];
if (channel == null) {
// Don't crash on theoretical race between async results-filtering
// and losing data for the channel.
Expand Down Expand Up @@ -382,7 +382,7 @@ class _ChannelLinkAutocompleteItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final store = PerAccountStoreWidget.of(context);
final channel = store.streams[option.channelId];
final channel = store.channels[option.channelId];

if (channel == null) return SizedBox.shrink();

Expand Down
8 changes: 4 additions & 4 deletions lib/widgets/compose_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ class _StreamContentInputState extends State<_StreamContentInput> {
final store = PerAccountStoreWidget.of(context);
final zulipLocalizations = ZulipLocalizations.of(context);

final channelName = store.streams[widget.narrow.channelId]?.name
final channelName = store.channels[widget.narrow.channelId]?.name
?? zulipLocalizations.unknownChannelName;
final hintTopic = _hintTopic();
final hintDestination = hintTopic == null
Expand Down Expand Up @@ -891,7 +891,7 @@ class _FixedDestinationContentInput extends StatelessWidget {
switch (narrow) {
case TopicNarrow(:final channelId, :final topic):
final store = PerAccountStoreWidget.of(context);
final channelName = store.streams[channelId]?.name
final channelName = store.channels[channelId]?.name
?? zulipLocalizations.unknownChannelName;
return zulipLocalizations.composeBoxChannelContentHint(
// No i18n of this use of "#" and ">" string; those are part of how
Expand Down Expand Up @@ -2251,7 +2251,7 @@ class _ComposeBoxState extends State<ComposeBox> with PerAccountStoreAwareStateM
switch (widget.narrow) {
case ChannelNarrow(:final channelId):
case TopicNarrow(:final channelId):
final channel = store.streams[channelId];
final channel = store.channels[channelId];
if (channel == null || !store.selfHasContentAccess(channel)) {
return _Banner(
intent: _BannerIntent.info,
Expand Down Expand Up @@ -2323,7 +2323,7 @@ class _ComposeBoxState extends State<ComposeBox> with PerAccountStoreAwareStateM
switch (narrow) {
case ChannelNarrow(:final channelId):
case TopicNarrow(:final channelId):
final channel = store.streams[channelId];
final channel = store.channels[channelId];
// (If the channel is unknown, we should have already decided
// what to show.)
assert(channel != null);
Expand Down
Loading
Loading