Skip to content
12 changes: 12 additions & 0 deletions assets/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,18 @@
"@errorBannerCannotPostInChannelLabel": {
"description": "Error-banner text replacing the compose box when you do not have permission to send a message to the channel."
},
"composeBoxBannerLabelUnsubscribedWhenCannotSend": "New messages will not appear automatically.",
"@composeBoxBannerLabelUnsubscribedWhenCannotSend": {
"description": "Label text for a compose-box banner when you are viewing an unsubscribed channel in which you do not have permission to send messages."
},
"composeBoxBannerButtonRefresh": "Refresh",
"@composeBoxBannerButtonRefresh": {
"description": "Label text for the 'Refresh' button in the compose-box banner when you are viewing an unsubscribed channel."
},
"composeBoxBannerButtonSubscribe": "Subscribe",
"@composeBoxBannerButtonSubscribe": {
"description": "Label text for the 'Subscribe' button in the compose-box banner when you are viewing an unsubscribed channel."
},
"composeBoxBannerLabelEditMessage": "Edit message",
"@composeBoxBannerLabelEditMessage": {
"description": "Label text for the compose-box banner when you are editing a message."
Expand Down
18 changes: 18 additions & 0 deletions lib/generated/l10n/zulip_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,24 @@ abstract class ZulipLocalizations {
/// **'You do not have permission to post in this channel.'**
String get errorBannerCannotPostInChannelLabel;

/// Label text for a compose-box banner when you are viewing an unsubscribed channel in which you do not have permission to send messages.
///
/// In en, this message translates to:
/// **'New messages will not appear automatically.'**
String get composeBoxBannerLabelUnsubscribedWhenCannotSend;

/// Label text for the 'Refresh' button in the compose-box banner when you are viewing an unsubscribed channel.
///
/// In en, this message translates to:
/// **'Refresh'**
String get composeBoxBannerButtonRefresh;

/// Label text for the 'Subscribe' button in the compose-box banner when you are viewing an unsubscribed channel.
///
/// In en, this message translates to:
/// **'Subscribe'**
String get composeBoxBannerButtonSubscribe;

/// Label text for the compose-box banner when you are editing a message.
///
/// In en, this message translates to:
Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'You do not have permission to post in this channel.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Edit message';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,16 @@ class ZulipLocalizationsDe extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'Du hast keine Berechtigung in diesen Kanal zu schreiben.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Nachricht bearbeiten';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'You do not have permission to post in this channel.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Edit message';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_fr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,16 @@ class ZulipLocalizationsFr extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'Vous n\'avez pas l\'autorisation de poster sur ce canal.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Editer le message';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_it.dart
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,16 @@ class ZulipLocalizationsIt extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'Non hai l\'autorizzazione per postare su questo canale.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Modifica messaggio';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_ja.dart
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,16 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
@override
String get errorBannerCannotPostInChannelLabel => 'このチャンネルに投稿する権限がありません。';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'メッセージを編集';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_nb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'You do not have permission to post in this channel.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Edit message';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_pl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,16 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'Nie masz uprawnień do dodawania wpisów w tym kanale.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Zmień wiadomość';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_ru.dart
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,16 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'У вас нет права писать в этом канале.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Редактирование сообщения';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_sk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'You do not have permission to post in this channel.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Edit message';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_sl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,16 @@ class ZulipLocalizationsSl extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'Nimate dovoljenja za objavljanje v tem kanalu.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Uredi sporočilo';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_uk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,16 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'Ви не маєте дозволу на публікацію в цьому каналі.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Редагування повідомлення';

Expand Down
10 changes: 10 additions & 0 deletions lib/generated/l10n/zulip_localizations_zh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ class ZulipLocalizationsZh extends ZulipLocalizations {
String get errorBannerCannotPostInChannelLabel =>
'You do not have permission to post in this channel.';

@override
String get composeBoxBannerLabelUnsubscribedWhenCannotSend =>
'New messages will not appear automatically.';

@override
String get composeBoxBannerButtonRefresh => 'Refresh';

@override
String get composeBoxBannerButtonSubscribe => 'Subscribe';

@override
String get composeBoxBannerLabelEditMessage => 'Edit message';

Expand Down
8 changes: 5 additions & 3 deletions lib/model/message_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -622,9 +622,10 @@ class MessageListView with ChangeNotifier, _MessageSequence {
Narrow get narrow => _narrow;
Narrow _narrow;

/// Set [narrow] to [newNarrow], reset, [notifyListeners], and [fetchInitial].
void renarrowAndFetch(Narrow newNarrow) {
/// Set [narrow] and [anchor], reset, [notifyListeners], and [fetchInitial].
void renarrowAndFetch(Narrow newNarrow, Anchor anchor) {
_narrow = newNarrow;
_anchor = anchor;
_reset();
notifyListeners();
fetchInitial();
Expand Down Expand Up @@ -1173,7 +1174,8 @@ class MessageListView with ChangeNotifier, _MessageSequence {
switch (propagateMode) {
case PropagateMode.changeAll:
case PropagateMode.changeLater:
renarrowAndFetch(newNarrow);
// TODO(#1009) anchor to some visible message, if any
renarrowAndFetch(newNarrow, anchor);
case PropagateMode.changeOne:
}
}
Expand Down
22 changes: 1 addition & 21 deletions lib/widgets/action_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -490,27 +490,7 @@ class SubscribeButton extends ActionSheetMenuItemButton {

@override
void onPressed() async {
final store = PerAccountStoreWidget.of(pageContext);
final channel = store.streams[channelId];
if (channel == null || channel is Subscription) return; // TODO could give feedback

try {
await subscribeToChannel(store.connection, subscriptions: [channel.name]);
} catch (e) {
if (!pageContext.mounted) return;

String? errorMessage;
switch (e) {
case ZulipApiException():
errorMessage = e.message;
// TODO(#741) specific messages for common errors, like network errors
// (support with reusable code)
default:
}

final title = ZulipLocalizations.of(pageContext).subscribeFailedTitle;
showErrorDialog(context: pageContext, title: title, message: errorMessage);
}
await ZulipAction.subscribeToChannel(pageContext, channelId: channelId);
}
}

Expand Down
26 changes: 26 additions & 0 deletions lib/widgets/actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,32 @@ abstract final class ZulipAction {
return fetchedMessage?.content;
}

static Future<void> subscribeToChannel(BuildContext context, {
required int channelId,
}) async {
final store = PerAccountStoreWidget.of(context);
final channel = store.streams[channelId];
if (channel == null || channel is Subscription) return; // TODO could give feedback

try {
await channels_api.subscribeToChannel(store.connection, subscriptions: [channel.name]);
} catch (e) {
if (!context.mounted) return;

String? errorMessage;
switch (e) {
case ZulipApiException():
errorMessage = e.message;
// TODO(#741) specific messages for common errors, like network errors
// (support with reusable code)
default:
}

final title = ZulipLocalizations.of(context).subscribeFailedTitle;
showErrorDialog(context: context, title: title, message: errorMessage);
}
}

/// Unsubscribe from a channel, possibly after a confirmation dialog,
/// showing an error dialog on failure.
///
Expand Down
20 changes: 19 additions & 1 deletion lib/widgets/button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ class ZulipWebUiKitButton extends StatelessWidget {
});
case (ZulipWebUiKitButtonAttention.medium, ZulipWebUiKitButtonIntent.neutral):
case (ZulipWebUiKitButtonAttention.high, ZulipWebUiKitButtonIntent.neutral):
case (ZulipWebUiKitButtonAttention.minimal, ZulipWebUiKitButtonIntent.warning):
throw UnimplementedError();
case (ZulipWebUiKitButtonAttention.medium, ZulipWebUiKitButtonIntent.warning):
return WidgetStateColor.fromMap({
WidgetState.pressed: designVariables.btnBgAttMediumIntWarningActive,
~WidgetState.pressed: designVariables.btnBgAttMediumIntWarningNormal,
});
case (ZulipWebUiKitButtonAttention.high, ZulipWebUiKitButtonIntent.warning):
return WidgetStateColor.fromMap({
WidgetState.pressed: designVariables.btnBgAttHighIntWarningActive,
~WidgetState.pressed: designVariables.btnBgAttHighIntWarningNormal,
});
case (ZulipWebUiKitButtonAttention.minimal, ZulipWebUiKitButtonIntent.info):
throw UnimplementedError();
case (ZulipWebUiKitButtonAttention.medium, ZulipWebUiKitButtonIntent.info):
Expand All @@ -63,6 +75,12 @@ class ZulipWebUiKitButton extends StatelessWidget {
return designVariables.neutralButtonLabel.withFadedAlpha(0.85);
case (ZulipWebUiKitButtonAttention.medium, ZulipWebUiKitButtonIntent.neutral):
case (ZulipWebUiKitButtonAttention.high, ZulipWebUiKitButtonIntent.neutral):
case (ZulipWebUiKitButtonAttention.minimal, ZulipWebUiKitButtonIntent.warning):
throw UnimplementedError();
case (ZulipWebUiKitButtonAttention.medium, ZulipWebUiKitButtonIntent.warning):
return designVariables.btnLabelAttMediumIntWarning;
case (ZulipWebUiKitButtonAttention.high, ZulipWebUiKitButtonIntent.warning):
return designVariables.btnLabelAttHighIntWarning;
case (ZulipWebUiKitButtonAttention.minimal, ZulipWebUiKitButtonIntent.info):
throw UnimplementedError();
case (ZulipWebUiKitButtonAttention.medium, ZulipWebUiKitButtonIntent.info):
Expand Down Expand Up @@ -195,7 +213,7 @@ enum ZulipWebUiKitButtonAttention {

enum ZulipWebUiKitButtonIntent {
neutral,
// warning,
warning,
// danger,
info,
// success,
Expand Down
Loading