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

Better management of archived channel names #1344

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

chimnayajith
Copy link

Pull Request

Description

This PR improves archived stream support in the mobile app to match the web app’s behavior. Key updates include:

  • Appending " (archived)" to stream names when viewing messages.
  • Updating UI elements (e.g., stream headers) to clearly indicate archived streams.
  • Filtering out archived channels from relevant pages.
  • Displaying the archived tag in a distinct font and color, consistent with the web app.
  • Replacing the compose box with a "no permission" error banner instead of offering message composition.

Related Issues

Screenshots

@chimnayajith chimnayajith force-pushed the 800-archived-channels branch 2 times, most recently from 24ed3b6 to 432b103 Compare February 11, 2025 19:37
@PIG208 PIG208 self-assigned this Feb 12, 2025
@PIG208 PIG208 added the maintainer review PR ready for review by Zulip maintainers label Feb 12, 2025
@PIG208 PIG208 self-requested a review February 12, 2025 20:46
Copy link
Member

@PIG208 PIG208 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! One more thing that I think needs to be handled is the topic actions sheet. None of the supported actions (follow/mute/unmute/resolve/unresolve) works on a topic in an archived channel. Not sure what's the best way to deal with this, though. It would be a good question to ask on #mobile-design.

Comment on lines 1413 to 1414
if (channel == null || !store.hasPostingPermission(inChannel: channel,
user: selfUser, byDate: DateTime.now())) {
user: selfUser, byDate: DateTime.now()) || channel.isArchived) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: let's reformat this to show that these expressions are parallel:

Suggested change
if (channel == null || !store.hasPostingPermission(inChannel: channel,
user: selfUser, byDate: DateTime.now())) {
user: selfUser, byDate: DateTime.now()) || channel.isArchived) {
if (channel == null
|| !store.hasPostingPermission(inChannel: channel,
user: selfUser, byDate: DateTime.now())
|| channel.isArchived) {

testWidgets('error banner is shown in $narrowType narrow', (tester) async {
await prepareComposeBox(tester,
narrow: narrow,
selfUser: eg.user(role: UserRole.administrator),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the user role relevant here? If not, this can be removed.

pinned.add(subscription);
} else {
unpinned.add(subscription);
if(!subscription.isArchived) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can use continue here, so that the ifs don't need to be nested

@@ -187,10 +189,13 @@ class _SubscriptionList extends StatelessWidget {

@override
Widget build(BuildContext context) {
// Filtering out the archived subscriptions.
final activeSubscriptions = subscriptions.where((sub) => !sub.isArchived).toList();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line of code is pretty straightforward, and the comment doesn't add much here, so let's just leave it out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, is it possible for subscriptions to contain archived subscriptions, or is it the job of SubscriptionListPageBody to ensure that no archived subscriptions are passed here?

If the latter, it might be better performance-wise to have an assertion that none of these subscriptions is archived, so that we don't need to re-filter the subscriptions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah now that I check, its already being handled. removed this part.

eg.subscription(eg.stream(streamId: 1, isArchived: true), pinToTop: true),
eg.subscription(eg.stream(streamId: 2), pinToTop: true),
eg.subscription(eg.stream(streamId: 3, isArchived: true), pinToTop: false),
eg.subscription(eg.stream(streamId: 4,), pinToTop: false),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra comma

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also reorder the list to make it easier to read:

    await setupStreamListPage(tester, subscriptions: [
      eg.subscription(eg.stream(streamId: 1, isArchived: true), pinToTop: true),
      eg.subscription(eg.stream(streamId: 2, isArchived: true), pinToTop: false),
      eg.subscription(eg.stream(streamId: 3), pinToTop: true),
      eg.subscription(eg.stream(streamId: 4), pinToTop: false),
    ]);

@@ -1062,7 +1085,7 @@ void main() {
.initNarrow.equals(DmNarrow.withUser(eg.otherUser.userId, selfUserId: eg.selfUser.userId));
await tester.pumpAndSettle();
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks unintentional.

fontStyle: FontStyle.italic,
),
),
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a specific design that we are following here (and other UI changes), it would be helpful to have a link in the commit message.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't a particular design that i could reference. I'm trying to keep it consistent with web.

@@ -595,6 +616,36 @@ void main() {
check(rectAfterTap).equals(rectBeforeTap);
});

testWidgets('shows archived label for archived streams', (tester) async {
final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tests, it is fine to not use ZulipLocalizations and have plain strings unless we are specifically testing something related to l10n. This way we have a better idea of what exactly we are expecting in tests.

]);

// Only non-archived streams
check(getItemCount()).equals(2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit ambiguous because it doesn't check if the remaining streams are the ones that are not archived.

@@ -347,6 +347,8 @@ class ZulipStream {
// TODO(server-8): added in FL 199, was previously only on [Subscription] objects
int? streamWeeklyTraffic;

final bool isArchived;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Make sure to match the order of these fields in the API documentation. See the dartdoc of ZulipStream to find the relevant piece.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be the order in the API documentation as I checked. Please let me know if its not

https://zulip.com/api/register-queue and go to subscriptions return value

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. The location the dartdoc points to has a different order. Let's match that:

/// For docs, search for "if stream"
/// in <https://zulip.com/api/register-queue>.
@JsonSerializable(fieldRename: FieldRename.snake)
class ZulipStream {

This enables the client to receive metadata about archived streams
in the register response and events, allowing it to handle them properly.
@chimnayajith chimnayajith force-pushed the 800-archived-channels branch 2 times, most recently from 6a37c0c to 1a8ae0f Compare February 28, 2025 02:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintainer review PR ready for review by Zulip maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support better management of names of archived channels
2 participants