Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
423 commits
Select commit Hold shift + click to select a range
f57ea71
content test [nfc]: Use const for math block tests
rajveermalviya Apr 24, 2025
d303cc0
content test [nfc]: Enable skips in testParseExample and testParse
gnprice May 29, 2025
71b16af
content [nfc]: Inline _logError in _KatexParser._parseSpan
rajveermalviya May 8, 2025
b812cde
content [nfc]: Refactor _KatexParser._parseChildSpans to take list of…
rajveermalviya May 8, 2025
e7053c2
content: Populate `debugHtmlNode` for KatexNode
rajveermalviya May 27, 2025
d798810
content [nfc]: Reintroduce KatexNode as a base sealed class
rajveermalviya Apr 24, 2025
10620d7
content: Ignore more KaTeX classes that don't have CSS definition
rajveermalviya May 19, 2025
e971402
content: Handle 'mspace' and 'msupsub' KaTeX CSS classes
rajveermalviya May 19, 2025
44305ef
content [nfc]: Explain why KaTeX .mspace requires no action
gnprice Jul 2, 2025
86dbcf8
content: Support parsing and handling inline styles for KaTeX content
rajveermalviya Apr 1, 2025
f003f58
content: Correctly apply font-size to interpret "em" on the same KaTe…
gnprice Jul 2, 2025
3438f08
content: Ignore KaTeX classes that don't have CSS definition
rajveermalviya Jun 17, 2025
0498916
content [nfc]: Explain why some KaTeX CSS classes are unused in its CSS
gnprice Jul 2, 2025
5e686f0
content [nfc]: Make MathNode a sealed class
rajveermalviya Jun 17, 2025
88ebff2
content [nfc]: Make `KatexHtmlParseError` private
rajveermalviya Jun 17, 2025
b11f758
content: Allow KaTeX parser to report failure reasons
rajveermalviya Jun 17, 2025
4b90a9a
tools/content: Support surveying unimplemented KaTeX features
rajveermalviya Jun 17, 2025
80dcd47
tools/content: Add a flag to control verbosity of KaTeX check result
rajveermalviya Jun 18, 2025
898d907
api [nfc]: Remove backward-compat code for mark-read protocol in FL <155
chrisbobbe Jul 2, 2025
58f5c7c
content: Initial support for inline <audio>, showing source links
rajveermalviya Jun 30, 2025
7143368
version: Sync version and changelog from v30.0.259 release
gnprice Jul 3, 2025
3f52e04
docs/release: Add warning that this document needs an update
gnprice Jul 3, 2025
dc5acec
docs/release: Document steps for "preview releases"
gnprice Jul 3, 2025
55e14f4
msglist [nfc]: Make a widget-like class for the app bar
chrisbobbe Jul 2, 2025
f420613
narrow [nfc]: Make Narrow.containsMessage return nullable bool
chrisbobbe Jul 2, 2025
38714de
msglist [nfc]: Add a notifyListeners, redundant but to simplify reaso…
chrisbobbe Jul 3, 2025
61a2319
msglist [nfc]: Add public renarrowAndFetch method, and use internally
chrisbobbe Jul 3, 2025
3ecdd50
icons: Add `remove` and `search`, from Figma
chrisbobbe Jul 3, 2025
6fcc009
internal_link [nfc]: Renumber a TODO that isn't about basic search
chrisbobbe Jul 3, 2025
8d68939
narrow [nfc]: Reorder ApiNarrowWith to be later, since more specific
chrisbobbe Jul 3, 2025
f1c6b56
msglist [nfc]: Fix a comment that wasn't quite right for starred/ment…
chrisbobbe Jul 3, 2025
8bf418e
model [nfc]: Remove a TODO about topic muting, which is already resolved
chrisbobbe Jul 3, 2025
dd49897
msglist [nfc]: Renumber a TODO about muting
chrisbobbe Jul 3, 2025
ac7be16
model: Temporarily cut matchContent, matchTopic from message objects
chrisbobbe Jul 3, 2025
a6104aa
msglist: Support basic keyword search
chrisbobbe Jul 2, 2025
997e2fc
msglist [nfc]: Pull out a _showAsMuted method
gnprice Jul 3, 2025
0ada484
l10n: Update translations from Weblate.
weblate Jul 3, 2025
d4d9711
recent-dms: Exclude DM conversations where all other recipients are m…
chrisbobbe Jun 10, 2025
c403608
msglist [nfc]: Place `_allMessagesVisible` right after `_messageVisible`
sm-sayedi May 22, 2025
ca03731
msglist [nfc]: s/VisibilityEffect/UserTopicVisibilityEffect/
chrisbobbe Jun 10, 2025
f7aff19
msglist: Exclude DMs if recipients muted (combined/mentions/starred/s…
chrisbobbe Jun 10, 2025
9815022
autocomplete: Exclude muted users from user-mention autocomplete
chrisbobbe Jun 10, 2025
eebd1ed
msglist [nfc]: Use `const` to avoid making new lists for nobody-is-ty…
chrisbobbe Jun 10, 2025
fcc2c8b
msglist: Exclude muted users from typing-status text
chrisbobbe Jun 10, 2025
cc87e0c
new-dm: Exclude muted users
chrisbobbe Jun 12, 2025
c70166b
deps: Upgrade Flutter to 3.33.0-1.0.pre.832
rajveermalviya Jul 7, 2025
776c7ce
deps: Upgrade firebase_core, firebase_messaging to latest
rajveermalviya Jul 7, 2025
86c679c
deps: Update pigeon to 25.5.0, from 25.3.2
rajveermalviya Jul 7, 2025
20da4ac
deps: Update drift to 2.27.0, from 2.26.1
rajveermalviya Jul 7, 2025
d313151
deps: Update video_player 2.10.0, from 2.9.5
rajveermalviya Jul 7, 2025
03c8c77
deps: Upgrade packages within constraints (tools/upgrade pub)
rajveermalviya Jul 7, 2025
2831798
deps android: Upgrade Gradle to 8.14.3, from 8.14.2
rajveermalviya Jul 7, 2025
5539e14
msglist: Decrease end-of-feed gap from 36px to 12px
chrisbobbe Jun 24, 2025
47ae5e3
msglist: Change end-of-feed 11px padding to 5px
chrisbobbe Jun 24, 2025
c4e03ff
unreads test: Add/use a checkInvariants function like in message-list…
chrisbobbe Jun 16, 2025
3bca476
unreads test [nfc]: Require isSortedWithoutDuplicates in fillWithMess…
chrisbobbe Jun 16, 2025
a518e4f
unreads test: Make room for two more message IDs (9, 10) in a test's …
chrisbobbe Jun 16, 2025
c1b3734
model: Add makeTopicKeyedMap for case-insensitive-but-preserving topi…
chrisbobbe Jun 17, 2025
ca17ee3
recent_senders: Treat topics case-insensitively
chrisbobbe Jun 18, 2025
7382bdf
unreads: Treat topics case-insensitively
chrisbobbe Jun 16, 2025
cf57281
test [nfc]: s/addUserTopic/setUserTopic/ in PerAccountStoreTestExtension
chrisbobbe Jun 18, 2025
a81e43a
model: Treat topics case-insensitively in topic-visibility
chrisbobbe Jun 18, 2025
79e0ca0
model: Restore matchContent/matchTopic but remove them in reconcileMe…
chrisbobbe Jul 8, 2025
04af371
msglist: Use icon for topic-list button in app bar
Komyyy Jul 8, 2025
742320c
home [nfc]: Clean up some dead safe-area code from before bottom-tabs
chrisbobbe Jul 7, 2025
37af86d
ci: Work around accidental desync of Flutter main branch
gnprice Jul 9, 2025
092d035
api: Set include_deactivated_groups client capability
gnprice Jul 7, 2025
7a40e0a
api: Add realmUserGroups to InitialSnapshot
gnprice Jul 7, 2025
c10a915
api: Add UserGroupEvent types
gnprice Jul 7, 2025
fc81428
store [nfc]: Spill "class PerAccountStore" line onto more lines
gnprice Jul 4, 2025
5b15b2a
group: Add UserGroupStore
gnprice Jul 7, 2025
63516ae
version: Sync version and changelog from v30.0.260 release
gnprice Jul 9, 2025
9cc34cd
ci: Further work around accidental desync of Flutter main branch
gnprice Jul 9, 2025
e96cad7
action_sheet test: Await a bottom-sheet exit that we hadn't been awai…
chrisbobbe Jun 24, 2025
c18ea48
content [nfc]: Move parseMessageContent here, from msglist; make public
chrisbobbe Jun 24, 2025
627003d
msglist [nfc]: s/{r,maybeR}evealMutedMessagesOf
chrisbobbe Jul 3, 2025
fb0d8ae
msglist [nfc]: Make SenderRow public
chrisbobbe Jun 24, 2025
a716333
action_sheet [nfc]: Pull out a `designVariables` local
chrisbobbe Jun 24, 2025
c0c586d
action_sheet [nfc]: Refactor some vertical padding, toward header param
chrisbobbe Jun 24, 2025
5996bb9
action_sheet [nfc]: In _showActionSheet, s/context/pageContext/
chrisbobbe Jun 24, 2025
0be1938
action_sheet: In _showActionSheet, wrap content in PerAccountStoreWidget
chrisbobbe Jun 24, 2025
2e0cceb
msglist [nfc]: Factor out MessageTimestampDisplay
chrisbobbe Jul 4, 2025
bf3fe42
action_sheet: Add `header` param; use it to show message content
chrisbobbe Jun 24, 2025
e6f4576
api: Require InitialSnapshot.userSettings, present since Zulip Server 5
chrisbobbe Jun 26, 2025
af95d11
api: Add InitialSnapshot.userSettings.presenceEnabled
chrisbobbe Jun 26, 2025
8108762
api: Add updateSettings route
chrisbobbe Jun 26, 2025
b8ccd55
button [nfc]: Extract MenuButton{,sShape} out to here, from action sheet
chrisbobbe Jun 26, 2025
2e6c293
button: Fix an inconsistency with Figma in MenuButton
chrisbobbe Jun 26, 2025
10c647f
button: Implement "toggle" component from Figma, for "Invisible mode"
chrisbobbe Jun 26, 2025
cc8c022
button: Give MenuButton an optional `toggle` param
chrisbobbe Jun 26, 2025
f81a698
profile test [nfc]: Split redundant group; make group for custom fields
chrisbobbe Jul 7, 2025
b491bd7
basic: Add a generic Option class
gnprice Jul 2, 2025
1201550
profile: Add toggle switch for "Invisible mode", with local echo
chrisbobbe Jun 26, 2025
d5da314
button: Fix MenuButton's icon color
chrisbobbe Jul 9, 2025
28455d8
button [nfc]: Add "list button" variant, factored into MenuButton widget
chrisbobbe Jul 9, 2025
9b5a637
profile: Change "Invisible mode" toggle to more neutral "list button"…
chrisbobbe Jul 9, 2025
95da571
store: Make GlobalStoreWidget's loading placeholder blank
rajveermalviya Jul 9, 2025
59dfd0a
ios: Use main background color as the splash screen
rajveermalviya Jul 9, 2025
0ee6336
api [nfc]: Add ReactionType.fromApiValue
sm-sayedi Jun 24, 2025
368df50
api: Add InitialSnapshot.userStatuses
sm-sayedi Jun 23, 2025
3d814d2
api: Add user_status event
sm-sayedi Jun 23, 2025
ce1c664
store: Add UserStore.getUserStatus, with event updates
sm-sayedi Jun 23, 2025
dc686ef
emoji [nfc]: Remove UnicodeEmojiWidget.notoColorEmojiTextSize
sm-sayedi Jul 7, 2025
3df6507
emoji [nfc]: Add ImageEmojiWidget.neverAnimate
sm-sayedi Jun 24, 2025
85db2af
content: Add UserStatusEmoji widget
sm-sayedi Jun 24, 2025
4b75025
test: Add `changeUserStatus(es)` to PerAccountStoreTestExtension
sm-sayedi Jun 26, 2025
a451d58
store [nfc]: s/isLoading/isRecoveringEventStream/
chrisbobbe Jul 7, 2025
f8b0e8b
store: Pass `dont_block` in first poll attempt after a failure
chrisbobbe Jul 7, 2025
02a2898
l10n: Update translations from Weblate.
weblate Jul 4, 2025
5677317
content [nfc]: Remove the `inline` property in _Katex widget
rajveermalviya May 19, 2025
b38301f
content test: Add offset and size based widget tests for KaTeX content
rajveermalviya Jul 7, 2025
bd353ef
content: Add a workaround for incorrect sizing in WidgetSpan, for KaTeX
rajveermalviya Jul 7, 2025
e8e8f41
content: Update base KaTeX text style to be explicit
rajveermalviya Jul 8, 2025
0ec1641
content: Scale inline KaTeX content based on the surrounding text
rajveermalviya Apr 22, 2025
85f4ecf
content: Handle 'strut' span in KaTeX content
rajveermalviya May 29, 2025
1fe817c
content: Handle positive margin-right and margin-left in KaTeX spans
rajveermalviya May 19, 2025
94037d7
version: Sync version and changelog from v30.0.261 release
gnprice Jul 10, 2025
d6affc9
ci: Fetch 3000 commits from upstream, rather than 1000
gnprice Jul 17, 2025
a3bbee9
ci: Revert temp hack for desync of Flutter main branch
gnprice Jul 17, 2025
a04b44e
msglist test: Fix a state leak from mutating eg.selfUser
gnprice Jul 18, 2025
16bec6a
content: Handle vertical offset spans in KaTeX content
rajveermalviya May 19, 2025
967a498
content: Error message for unexpected CSS class in vlist inner span
rajveermalviya Jun 20, 2025
74b08db
content: Implement debugDescribeChildren for KatexVlistRowNode
rajveermalviya Jul 17, 2025
c4503b4
content: Make sure there aren't any unexpected styles on `.vlist` span
rajveermalviya Jul 17, 2025
0507ac1
narrow: Introduce TopicNarrow.processTopicLikeServer
rajveermalviya Jul 18, 2025
806153c
msglist: Normalize topic name when opening message list
rajveermalviya Jul 18, 2025
09203d1
msglist test [nfc]: Clarify the topic-normalization test
gnprice Jul 19, 2025
344b5f6
content: Support negative margins on KaTeX spans
rajveermalviya Apr 1, 2025
01bff8e
content test: Add test for negative margins on a vlist row in KaTeX c…
rajveermalviya Jul 17, 2025
64956b8
content: Filter negative margin styles if present on a vlist row
rajveermalviya Jul 17, 2025
66d3ed9
doc: Add missing project board link in README.
apoorvapendse Jul 19, 2025
fe186b2
doc: Update milestone reference in README
gnprice Jul 21, 2025
b073c6b
content: Render KaTeX by default, the way we have in recent releases
gnprice Jun 12, 2025
b773c00
katex [nfc]: Show line numbers only on unknown hard-fails, not others
gnprice Jul 19, 2025
20294ed
katex [nfc]: Add messages for remaining hard-fail cases seen in corpus
gnprice Jul 19, 2025
545ecfa
tools/content [nfc]: Tie-break on reason text when number of failures…
gnprice Jul 19, 2025
1fd2f02
katex [nfc]: Cut stray import of widgets library
gnprice Jul 19, 2025
a914be5
binding [nfc]: Cut stray import of a widgets library
gnprice Jul 19, 2025
5ab997b
katex [nfc]: Fix a variable name to specify its units, namely em
gnprice Jul 18, 2025
e0d8044
katex: Require height on pstrut spans
gnprice Jul 18, 2025
8909476
katex [nfc]: Separate _parseInlineStyles from constructing a KatexSpa…
gnprice Jul 18, 2025
f935050
katex [nfc]: Push more parsing into _parseInlineStyles; return Map
gnprice Jul 18, 2025
eabcca1
katex [nfc]: Factor out _takeStyleEm from _parseSpanInlineStyles
gnprice Jul 18, 2025
95ae293
katex: Fix a misleading log line: unexpected CSS property, not value
gnprice Jul 18, 2025
b9c7bc4
katex [nfc]: Skip building whole KatexSpanStyles for struts' two prop…
gnprice Jul 18, 2025
8ac8a43
katex [nfc]: Cut vertical-align from generic style properties
gnprice Jul 18, 2025
d44e730
katex [nfc]: Check "only has height" directly, without making KatexSp…
gnprice Jul 18, 2025
b583793
katex [nfc]: Get pstrut height directly, without making KatexSpanStyles
gnprice Jul 18, 2025
c14bfe6
katex [nfc]: Directly handle expected inline styles on vlist child
gnprice Jul 18, 2025
73ae269
katex: Don't expect height on vlist child spans
gnprice Jul 19, 2025
fe383b8
katex [nfc]: Consolidate logic for computing overall styles of KatexS…
gnprice Jul 18, 2025
0f634c9
katex [nfc]: Inline remaining/main use of _parseSpanInlineStyles
gnprice Jul 18, 2025
f54d168
katex [nfc]: Construct vlist child's styles directly, without filter
gnprice Jul 18, 2025
ebce0a4
katex [nfc]: Dedupe logic for vlist child between margin/no-margin cases
gnprice Jul 18, 2025
2a604ba
katex [nfc]: Note that heightEm might turn out not to be needed
gnprice Jul 19, 2025
39fdded
katex [nfc]: Simplify extracting from attrs map in _parseInlineStyles
gnprice Jul 19, 2025
83a0b6f
katex [nfc]: Split out _parseStrut, _parseVlist, _parseGenericSpan
gnprice Jul 19, 2025
6304ea6
presence: Dispose Presence object when store disposed
gnprice Jul 18, 2025
9297b75
i18n: Sync translations from Weblate.
weblate Jul 18, 2025
d6a5020
action_sheet test: Avoid mutating shared example users
gnprice Jul 18, 2025
54ac1dd
recent-dms test: Avoid mutating eg.selfUser
gnprice Jul 18, 2025
5515540
test: Prevent mutation of shared example users
gnprice Jul 18, 2025
805afac
test [nfc]: Make all example-data globals final
gnprice Jul 18, 2025
83a9407
test: Prevent mutating shared example ServerEmojiData values
gnprice Jul 18, 2025
459ca98
katex test [nfc]: Split parsing tests to their own file, like impleme…
gnprice Jul 19, 2025
993bdc2
katex test [nfc]: Make the KaTeX examples instances of KatexExample
gnprice Jul 19, 2025
6f66b06
content test [nfc]: Move some helpers to top level, so importable
gnprice Jul 19, 2025
c5a10af
katex [nfc]: Move KaTeX widgets to their own file
gnprice Jul 19, 2025
7fb722e
katex test [nfc]: Make some examples more compact
gnprice Jul 19, 2025
15c68e0
katex test [nfc]: Simplify a bit with a KatexExample.block constructor
gnprice Jul 19, 2025
5e1211b
katex test [nfc]: Use Dart raw strings to avoid double-backslash
gnprice Jul 19, 2025
4b679d4
katex test [nfc]: Make a KatexExample.inline similar to .block
gnprice Jul 21, 2025
5e303dc
katex [nfc]: On KatexSpanNode constructor let text or nodes be omitted
gnprice Jul 19, 2025
8a39d04
katex [nfc]: Let KatexSpanNode.styles default to empty
gnprice Jul 19, 2025
5f85799
katex [nfc]: Add docs explaining the different content-node classes
gnprice Jul 19, 2025
dedeee6
test store [nfc]: Make changeUserStatuses take a Map instead of a Record
sm-sayedi Jul 17, 2025
b06417b
msglist: Show user status emoji
sm-sayedi Jun 26, 2025
a895412
test: Add find.text analogue with includePlaceholders option
gnprice Jul 22, 2025
395eb91
recent-dms: Show user status emoji in recent DMs page
sm-sayedi Jun 26, 2025
c99bd22
new-dm: Show user status emoji
sm-sayedi Jun 26, 2025
22f17e3
autocomplete [nfc]: Make MentionAutocompleteItem visibleForTesting
sm-sayedi Jul 17, 2025
dbc2348
autocomplete: Show user status emoji in user-mention autocomplete
sm-sayedi Jun 26, 2025
df8c5f8
profile: Show user status
sm-sayedi Jun 26, 2025
e9bbf4e
readme: Remove a "this beta app" reference
chrisbobbe Jul 22, 2025
608a24f
test [nfc]: Consolidate a widgets/checks.dart for trivial checks-exte…
gnprice Jul 22, 2025
f4094e3
test [nfc]: Consolidate per-file checks-extensions to widgets/checks.…
gnprice Jul 22, 2025
ae2b9a2
user [nfc]: Split avatar, presence, status widgets out from content.dart
gnprice Jul 22, 2025
5d54468
settings test: Check theme-setting radio buttons by checking semantics
chrisbobbe Jun 3, 2025
01655d6
settings test [nfc]: Pull out checkRadioButtonAppearsChecked helper
chrisbobbe Jun 17, 2025
d9aafc8
settings test: Add widget tests for latest settings
chrisbobbe Jun 17, 2025
193ee91
settings: Migrate to new RadioGroup API for radio buttons
chrisbobbe Jun 3, 2025
aaa1e66
message [nfc]: Simplify this copy of realmEmptyTopicDisplayName; expl…
gnprice Jul 7, 2025
d4afa40
message [nfc]: Use getter for realmEmptyTopicDisplayName rather than …
gnprice Jul 7, 2025
c5e1d23
realm [nfc]: Introduce RealmStore, initially vacuous
gnprice Jul 4, 2025
a578947
profile test: Have displayInProfileSummary default to false, not true
gnprice Jul 6, 2025
221ba81
test [nfc]: Move eg.customProfileField out from one test file
gnprice Jul 6, 2025
6b1f9af
store test: Test handling of customProfileFields
gnprice Jul 6, 2025
5efff58
realm [nfc]: Move data here from PerAccountStore
gnprice Jul 4, 2025
3098213
realm [nfc]: Move proxy boilerplate out of central store.dart
gnprice Jul 4, 2025
a2fa946
store [nfc]: Expose PerAccountStoreBase.core to subclasses
gnprice Jul 4, 2025
fea9e01
realm [nfc]: Add HasRealmStore for other substores to use
gnprice Jul 4, 2025
4b56bba
narrow [nfc]: Inline away TopicNarrow.processTopicLikeServer
gnprice Jul 23, 2025
45accee
realm [nfc]: Move processTopicLikeServer to substore, from API code
gnprice Jul 4, 2025
b30df8b
realm [nfc]: Add Duration getters for durations
gnprice Jul 4, 2025
290067a
presence [nfc]: Use RealmStore for server/realm settings
gnprice Jul 4, 2025
49539ff
realm [nfc]: Add server settings for typing status
gnprice Jul 4, 2025
2321e89
typing_status [nfc]: Use RealmStore for server settings
gnprice Jul 4, 2025
86ce025
dartdoc: Stop section-divider comments from getting absorbed into docs
gnprice Jul 6, 2025
2b045d2
realm [nfc]: Organize realm settings, from current API doc
gnprice Jul 4, 2025
1e11327
realm [nfc]: Cut duplicate, some out of date todo-comments on updating
gnprice Jul 4, 2025
5d0188f
store [nfc]: Organize substore parameters uniformly
gnprice Jul 4, 2025
db8809b
emoji [nfc]: Drop setServerEmojiData from main interface
gnprice Jul 6, 2025
1d62146
emoji [nfc]: Move proxy boilerplate out to substore file
gnprice Jul 7, 2025
d1b0812
user [nfc]: Provide RealmStore to UserStore
gnprice Jul 4, 2025
d71f081
user [nfc]: Move hasPassedWaitingPeriod here
gnprice Jul 4, 2025
9a5960a
user [nfc]: Move userDisplayEmail here
gnprice Jul 4, 2025
5233cfb
user [nfc]: Move proxy boilerplate out to substore file
gnprice Jul 7, 2025
623bcb4
user [nfc]: Add HasUserStore for other substores to use
gnprice Jul 6, 2025
fab85ca
channel [nfc]: Provide UserStore to ChannelStore
gnprice Jul 4, 2025
6b47ff0
channel [nfc]: Move hasPostingPermission here
gnprice Jul 4, 2025
72cf5d6
channel [nfc]: Move proxy boilerplate out to substore file
gnprice Apr 4, 2025
f83c9c1
message test [nfc]: Move sendMessage smoke test to follow sendMessage
gnprice Jul 6, 2025
9499dbe
message [nfc]: Consolidate "disposed" checks onto substore methods
gnprice Jul 4, 2025
4055216
message [nfc]: Drop reconcileMessages from main interface
gnprice Jul 6, 2025
2b0944f
message [nfc]: Move proxy boilerplate out to substore file
gnprice Jul 4, 2025
8c3b505
api [nfc]: Remove a comment about event_types that came from outdated…
chrisbobbe Jul 24, 2025
0ce94c4
analyze: Fix new lint on latest Flutter main
chrisbobbe Jul 23, 2025
d13e3d9
new-dm test: Split out muted-user checks as own test case
gnprice Jul 24, 2025
ff335a6
new-dm: Exclude deactivated users
gnprice Jul 24, 2025
a1246ee
user [nfc]: Document explicitly that allUsers includes deactivated
gnprice Jul 24, 2025
2fc55ab
lightbox test: Skip a no-hero test, pending rework for new page trans…
gnprice Jul 24, 2025
55d055f
deps: Upgrade Flutter to 3.33.0-1.0.pre-1086
sm-sayedi Jul 23, 2025
3addf69
deps: Revert unintentionally-broad upgrade
gnprice Jul 25, 2025
f9ec516
lightbox [nfc]: Go through MessageTimestampStyle for timestamp
chrisbobbe Jul 13, 2025
55b95d2
msglist [nfc]: Add two params to MessageTimestampStyle.format, to use…
chrisbobbe Jul 14, 2025
7704fd8
msglist [nfc]: Use ZulipBinding.instance.utcNow().toLocal() in DateText
chrisbobbe Jul 21, 2025
3703baa
msglist [nfc]: Finish centralizing on MessageTimestampStyle
chrisbobbe Jul 14, 2025
0a6b2f7
msglist test: Test all `MessageTimestampStyle`s, not just dateOnlyRel…
chrisbobbe Jul 23, 2025
4a77fbd
api: Start accepting null for user_settings.twenty_four_hour_time
chrisbobbe Jul 14, 2025
ddc9ade
model [nfc]: Pass TwentyFourHourTimeMode to MessageTimestampStyle.format
chrisbobbe Jul 15, 2025
1d1f426
msglist [nfc]: Remove a hard-coded 'en_US' which is the default
chrisbobbe Jul 15, 2025
b7146a7
msglist [nfc]: s/_timeOnlyFormat/_timeFormat/
chrisbobbe Jul 15, 2025
91d4ef3
msglist [nfc]: Pull out a _timeFormatWithSeconds helper
chrisbobbe Jul 15, 2025
4d4928f
msglist [nfc]: Add helpers to resolve TwentyFourHourTimeMode
chrisbobbe Jul 21, 2025
736dc4d
msglist [nfc]: Use a helper field we just added
chrisbobbe Jul 21, 2025
92bae68
msglist: Follow user_settings.twenty_four_hour_time for message times…
chrisbobbe Jul 21, 2025
e120e00
content: Follow user_settings.twenty_four_hour_time in global times
chrisbobbe Jul 22, 2025
55e7067
l10n: Update translations from Weblate.
weblate Jul 25, 2025
11ffac2
version: Sync version and changelog from v30.0.262 release
gnprice Jul 25, 2025
077e33c
l10n: Update translations from Weblate.
weblate Jul 26, 2025
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
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ jobs:
# so that Flutter knows its version and sees the constraint in our
# pubspec is satisfied. It's uncommon for flutter/flutter to go
# more than 100 commits between tags. Fetch 1000 for good measure.
# TODO(upstream): Around 2025-05, Flutter upstream stopped making
# tags within the main/master branch. Get that fixed:
# https://github.com/zulip/zulip-flutter/issues/1710
# Pending that, fetch more than 1000 commits.
run: |
git clone --depth=1000 -b main https://github.com/flutter/flutter ~/flutter
git clone --depth=3000 -b main https://github.com/flutter/flutter ~/flutter
TZ=UTC git --git-dir ~/flutter/.git log -1 --format='%h | %ci | %s' --date=iso8601-local
echo ~/flutter/bin >> "$GITHUB_PATH"

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/update-translations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ jobs:
# so that Flutter knows its version and sees the constraint in our
# pubspec is satisfied. It's uncommon for flutter/flutter to go
# more than 100 commits between tags. Fetch 1000 for good measure.
# TODO(upstream): See ci.yml for why we fetch more than 1000.
run: |
git clone --depth=1000 -b main https://github.com/flutter/flutter ~/flutter
git clone --depth=3000 -b main https://github.com/flutter/flutter ~/flutter
TZ=UTC git --git-dir ~/flutter/.git log -1 --format='%h | %ci | %s' --date=iso8601-local
echo ~/flutter/bin >> "$GITHUB_PATH"

Expand Down
41 changes: 21 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
# Zulip Flutter (beta)
# Zulip Flutter

A Zulip client for Android and iOS, using Flutter.
The official Zulip app for Android and iOS, built with Flutter.

This app is currently [in beta][beta].
When it's ready, it [will become the new][] official mobile Zulip client.
To see what work is planned before that launch,
see the [milestones][] and the [project board][].

[beta]: https://chat.zulip.org/#narrow/stream/2-general/topic/Flutter/near/1708728
[will become the new]: https://chat.zulip.org/#narrow/stream/2-general/topic/Flutter/near/1582367
[milestones]: https://github.com/zulip/zulip-flutter/milestones?direction=asc&sort=title
[project board]: https://github.com/orgs/zulip/projects/5/views/4
This app [was launched][] as the main Zulip mobile app
in June 2025.
It replaced the [previous Zulip mobile app][] built with React Native.

[was launched]: https://blog.zulip.com/flutter-mobile-app-launch
[previous Zulip mobile app]: https://github.com/zulip/zulip-mobile#readme

## Using Zulip

To use Zulip on iOS or Android, install the [official mobile Zulip client][].
## Get the app

You can also [try out this beta app][beta].

[official mobile Zulip client]: https://github.com/zulip/zulip-mobile#readme
Release versions of the app are available here:
* [Zulip for iOS](https://apps.apple.com/app/zulip/id1203036395)
on Apple's App Store
* [Zulip for Android](https://play.google.com/store/apps/details?id=com.zulipmobile)
on the Google Play Store
* Or if you don't use Google Play, you can
[download an APK](https://github.com/zulip/zulip-flutter/releases/latest)
from the official build we post on GitHub.


## Contributing

Contributions to this app are welcome.

If you're looking to participate in Google Summer of Code with Zulip,
this is one of the projects we intend to accept [GSoC 2025 applications][gsoc]
for.
this was among the projects we accepted [GSoC applications][gsoc] for
in 2024 and 2025.

[gsoc]: https://zulip.readthedocs.io/en/latest/outreach/gsoc.html#mobile-app

Expand All @@ -42,7 +42,7 @@ browsing through recent commits and the codebase,
and the Zulip guide to Git.

To find possible issues to work on, see our [project board][].
Look for issues up through the "Launch" milestone,
Look for issues in the earliest milestone,
and that aren't already assigned.

Follow the Zulip guide to [picking an issue to work on][],
Expand All @@ -55,6 +55,7 @@ and describing your progress.

[your first codebase contribution]: https://zulip.readthedocs.io/en/latest/contributing/contributing.html#your-first-codebase-contribution
[what makes a great Zulip contributor]: https://zulip.readthedocs.io/en/latest/contributing/contributing.html#what-makes-a-great-zulip-contributor
[project board]: https://github.com/orgs/zulip/projects/5/views/4
[picking an issue to work on]: https://zulip.readthedocs.io/en/latest/contributing/contributing.html#picking-an-issue-to-work-on


Expand Down Expand Up @@ -108,7 +109,7 @@ Two specific points to expand on:
[commit-style]: https://zulip.readthedocs.io/en/latest/contributing/commit-discipline.html


## Getting started in developing this beta app
## Getting started in developing

### Setting up

Expand Down
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ android {
}

defaultConfig {
applicationId "com.zulip.flutter"
applicationId "com.zulipmobile"
minSdkVersion 28
targetSdkVersion flutter.targetSdkVersion
// These are synced to local.properties from pubspec.yaml by the flutter tool.
Expand Down
4 changes: 2 additions & 2 deletions android/app/lint-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="6" by="lint 8.5.2" type="baseline" client="gradle" dependencies="false" name="AGP (8.5.2)" variant="all" version="8.5.2">
<issues format="6" by="lint 8.10.0" type="baseline" client="gradle" dependencies="false" name="AGP (8.10.0)" variant="all" version="8.10.0">

<!--TODO(#855) see if this is no longer needed-->
<issue
id="InvalidPackage"
message="Invalid package reference in library; not included in Android: `javax.xml.stream`. Referenced from `org.apache.tika.utils.XMLReaderUtils`.">
<location
file="$GRADLE_USER_HOME/caches/modules-2/files-2.1/org.apache.tika/tika-core/3.1.0/6ba44a9ddf8f6f2b4bc88e8bc64269aea0424607/tika-core-3.1.0.jar"/>
file="$GRADLE_USER_HOME/caches/modules-2/files-2.1/org.apache.tika/tika-core/3.2.0/9232bb3c71f231e8228f570071c0e1ea29d40115/tika-core-3.2.0.jar"/>
</issue>

</issues>
2 changes: 1 addition & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="Zulip beta"
android:label="Zulip"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Autogenerated from Pigeon (v25.3.1), do not edit directly.
// Autogenerated from Pigeon (v25.5.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")

Expand All @@ -13,7 +13,7 @@ import io.flutter.plugin.common.StandardMethodCodec
import io.flutter.plugin.common.StandardMessageCodec
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer
private object NotificationsPigeonUtils {
private object AndroidNotificationsPigeonUtils {

fun wrapResult(result: Any?): List<Any?> {
return listOf(result)
Expand Down Expand Up @@ -128,7 +128,7 @@ data class NotificationChannel (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -171,7 +171,7 @@ data class AndroidIntent (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -215,7 +215,7 @@ data class PendingIntent (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -249,7 +249,7 @@ data class InboxStyle (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -299,7 +299,7 @@ data class Person (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -339,7 +339,7 @@ data class MessagingStyleMessage (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -382,7 +382,7 @@ data class MessagingStyle (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -419,7 +419,7 @@ data class Notification (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -459,7 +459,7 @@ data class StatusBarNotification (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
Expand Down Expand Up @@ -509,11 +509,11 @@ data class StoredNotificationSound (
if (this === other) {
return true
}
return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) }
return AndroidNotificationsPigeonUtils.deepEquals(toList(), other.toList()) }

override fun hashCode(): Int = toList().hashCode()
}
private open class NotificationsPigeonCodec : StandardMessageCodec() {
private open class AndroidNotificationsPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
129.toByte() -> {
Expand Down Expand Up @@ -721,7 +721,7 @@ interface AndroidNotificationHostApi {
companion object {
/** The codec used by AndroidNotificationHostApi. */
val codec: MessageCodec<Any?> by lazy {
NotificationsPigeonCodec()
AndroidNotificationsPigeonCodec()
}
/** Sets up an instance of `AndroidNotificationHostApi` to handle messages through the `binaryMessenger`. */
@JvmOverloads
Expand All @@ -737,7 +737,7 @@ interface AndroidNotificationHostApi {
api.createNotificationChannel(channelArg)
listOf(null)
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -752,7 +752,7 @@ interface AndroidNotificationHostApi {
val wrapped: List<Any?> = try {
listOf(api.getNotificationChannels())
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -770,7 +770,7 @@ interface AndroidNotificationHostApi {
api.deleteNotificationChannel(channelIdArg)
listOf(null)
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -785,7 +785,7 @@ interface AndroidNotificationHostApi {
val wrapped: List<Any?> = try {
listOf(api.listStoredSoundsInNotificationsDirectory())
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -803,7 +803,7 @@ interface AndroidNotificationHostApi {
val wrapped: List<Any?> = try {
listOf(api.copySoundResourceToMediaStore(targetFileDisplayNameArg, sourceResourceNameArg))
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand Down Expand Up @@ -835,7 +835,7 @@ interface AndroidNotificationHostApi {
api.notify(tagArg, idArg, autoCancelArg, channelIdArg, colorArg, contentIntentArg, contentTextArg, contentTitleArg, extrasArg, groupKeyArg, inboxStyleArg, isGroupSummaryArg, messagingStyleArg, numberArg, smallIconResourceNameArg)
listOf(null)
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -852,7 +852,7 @@ interface AndroidNotificationHostApi {
val wrapped: List<Any?> = try {
listOf(api.getActiveNotificationMessagingStyleByTag(tagArg))
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -869,7 +869,7 @@ interface AndroidNotificationHostApi {
val wrapped: List<Any?> = try {
listOf(api.getActiveNotifications(desiredExtrasArg))
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand All @@ -888,7 +888,7 @@ interface AndroidNotificationHostApi {
api.cancel(tagArg, idArg)
listOf(null)
} catch (exception: Throwable) {
NotificationsPigeonUtils.wrapError(exception)
AndroidNotificationsPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
Expand Down
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher_background.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher_background.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ android.enableJetifier=true
# Defining them here makes them available both in
# settings.gradle and in the build.gradle files.

agpVersion=8.10.0
agpVersion=8.10.1

# Generally update this to the version found in recent releases
# of Android Studio, as listed in this table:
Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# the wrapper is the one from the new Gradle too.)
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
20 changes: 0 additions & 20 deletions assets/app-icons/zulip-beta-combined.svg

This file was deleted.

Loading