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

Sort channel names the same way as Zulip web #1165

Open
gnprice opened this issue Dec 16, 2024 · 4 comments
Open

Sort channel names the same way as Zulip web #1165

gnprice opened this issue Dec 16, 2024 · 4 comments
Labels
a-home The home screens of the app; finding and starting conversations a-i18n Translation, localization, internationalization upstream Would benefit from work in Flutter or another upstream
Milestone

Comments

@gnprice
Copy link
Member

gnprice commented Dec 16, 2024

On the subscriptions / channels page, the sorting of channels by name doesn't fully match the behavior we have in the Zulip web app. In particular, we got a user report that names starting with an emoji are being sorted to the end, while they appear at the beginning in Zulip web.

We should match the ordering of Zulip web, so that people see their channels in the same order when they move between using Zulip on one platform vs. another.

If doing so exactly is impractical or difficult, then we should (a) do a hack that at least handles an emoji at the start of the name, matching Zulip web's ordering for emoji vs. non-emoji and for emoji vs. other emoji; and (b) file a follow-up issue for matching the ordering exactly.

Implementation

The name isn't the only key that the subscriptions / channels list is sorted by; it's also sorted by the channel's status as pinned and/or muted. The role of pinning and muting should remain unchanged.

This issue applies to everywhere a list of channels appears. That means:

@gnprice gnprice added a-i18n Translation, localization, internationalization a-home The home screens of the app; finding and starting conversations labels Dec 16, 2024
@gnprice gnprice added this to the M6: Post-launch milestone Dec 16, 2024
@gnprice gnprice added the beta feedback Things beta users have specifically asked for label Dec 16, 2024
@chrisbobbe
Copy link
Collaborator

chrisbobbe commented Dec 18, 2024

Web's left sidebar has three headered groups: "Pinned", "Active", "Inactive", in that order. Within a group, non-muted channels come before muted ones.

After that, sorting is done on channels' names with this compare function:

// If we can, use a locale-aware sorter.  However, if the browser
// doesn't support the ECMAScript Internationalization API
// Specification, do a dumb string comparison because
// String.localeCompare is really slow.
export function make_strcmp(): (x: string, y: string) => number {
    try {
        const collator = new Intl.Collator();
        return collator.compare.bind(collator);
    } catch {
        // continue regardless of error
    }

    return function util_strcmp(a: string, b: string): number {
        return a < b ? -1 : a > b ? 1 : 0;
    };
}

export const strcmp = make_strcmp();

I assume the Intl.Collator behavior is what most web-app users get these days.

Dart doesn't have an analog of Intl.Collator. Could we get close to that behavior by using ICU (probably libicui18n?) via ffi?

Otherwise, would unorm_dart be useful for this? That library has come up as the preferred library for filtering lists of strings insensitively to diacritics, like #1067. No, turns out this doesn't offer anything for sorting.

@gnprice
Copy link
Member Author

gnprice commented Dec 23, 2024

Thanks, that's helpful!

Yeah, I think using an ICU library via FFI is probably the full solution. That could be something we do ourselves once FFI support is more mature, as the Flutter roadmap calls for next year. Or it looks like people are working on building such a thing for everyone (and for the full scope of ICU functionality): package:icu4x, published by "unicode.org". Still a work in progress but has Unicode engineers working with the Dart team to build the things they need to make it all work:

(And that is indeed using FFI; here's the Dart code implementing Collator.compare.)

In the meantime let's do this:

a hack that at least handles an emoji at the start of the name, matching Zulip web's ordering for emoji vs. non-emoji and for emoji vs. other emoji

I'll file a separate issue for that nearer-term hack, and edit this issue to focus on the full solution. (Revising the plan I said above.)

@gnprice
Copy link
Member Author

gnprice commented Dec 23, 2024

matching Zulip web's ordering […] for emoji vs. other emoji

This part will also require essentially the same data, so I'll leave it out of the near-term issue. The emoji portion of the ordering is in CLDR here:
https://unicode.org/cldr/charts/46/collation/root.html
https://github.com/unicode-org/cldr/blob/9bbbc7769d6/common/collation/root.xml#L924-L1364
(The spec path leads through https://tc39.es/ecma402/#sec-intl.collator.prototype.compare to https://unicode.org/reports/tr10/ . I don't think we'll ever want to spend the time to read the latter in full — that'll be ICU4X's job.)

We do have a separate plan to get a version of that emoji ordering data, from the server:

So once we've done that, we might revisit the hack to use that information, if this issue for the full solution is still open.

@gnprice
Copy link
Member Author

gnprice commented Dec 23, 2024

OK, filed:

And I'll push this back to M7 Future.

@gnprice gnprice modified the milestones: M6: Post-launch, M7: Future Dec 23, 2024
@gnprice gnprice added upstream Would benefit from work in Flutter or another upstream and removed beta feedback Things beta users have specifically asked for labels Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-home The home screens of the app; finding and starting conversations a-i18n Translation, localization, internationalization upstream Would benefit from work in Flutter or another upstream
Projects
Status: No status
Development

No branches or pull requests

2 participants