-
Notifications
You must be signed in to change notification settings - Fork 271
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
Handle Zulip internal links #305
Changes from all commits
2f944a0
1cfa5dc
c65bab8
664f4a5
2cf1b36
9a5ec69
4beb7bb
e3a2dcc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import 'dart:math'; | ||
|
||
import '../api/model/model.dart'; | ||
import '../api/model/narrow.dart'; | ||
import 'internal_link.dart'; | ||
import 'narrow.dart'; | ||
import 'store.dart'; | ||
|
||
|
@@ -101,82 +101,6 @@ String wrapWithBacktickFence({required String content, String? infoString}) { | |
return resultBuffer.toString(); | ||
} | ||
|
||
const _hashReplacements = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nits in commit message:
|
||
"%": ".", | ||
"(": ".28", | ||
")": ".29", | ||
".": ".2E", | ||
}; | ||
|
||
final _encodeHashComponentRegex = RegExp(r'[%().]'); | ||
|
||
// Corresponds to encodeHashComponent in Zulip web; | ||
// see web/shared/src/internal_url.ts. | ||
String _encodeHashComponent(String str) { | ||
return Uri.encodeComponent(str) | ||
.replaceAllMapped(_encodeHashComponentRegex, (Match m) => _hashReplacements[m[0]!]!); | ||
} | ||
|
||
/// A URL to the given [Narrow], on `store`'s realm. | ||
/// | ||
/// To include /near/{messageId} in the link, pass a non-null [nearMessageId]. | ||
// Why take [nearMessageId] in a param, instead of looking for it in [narrow]? | ||
// | ||
// A reasonable question: after all, the "near" part of a near link (e.g., for | ||
// quote-and-reply) does take the same form as other operator/operand pairs | ||
// that we represent with [ApiNarrowElement]s, like "/stream/48-mobile". | ||
// | ||
// But unlike those other elements, we choose not to give the "near" element | ||
// an [ApiNarrowElement] representation, because it doesn't have quite that role: | ||
// it says where to look in a list of messages, but it doesn't filter the list down. | ||
// In fact, from a brief look at server code, it seems to be *ignored* | ||
// if you include it in the `narrow` param in get-messages requests. | ||
// When you want to point the server to a location in a message list, you | ||
// you do so by passing the `anchor` param. | ||
Uri narrowLink(PerAccountStore store, Narrow narrow, {int? nearMessageId}) { | ||
final apiNarrow = narrow.apiEncode(); | ||
final fragment = StringBuffer('narrow'); | ||
for (ApiNarrowElement element in apiNarrow) { | ||
fragment.write('/'); | ||
if (element.negated) { | ||
fragment.write('-'); | ||
} | ||
|
||
if (element is ApiNarrowDm) { | ||
final supportsOperatorDm = store.connection.zulipFeatureLevel! >= 177; // TODO(server-7) | ||
element = element.resolve(legacy: !supportsOperatorDm); | ||
} | ||
|
||
fragment.write('${element.operator}/'); | ||
|
||
switch (element) { | ||
case ApiNarrowStream(): | ||
final streamId = element.operand; | ||
final name = store.streams[streamId]?.name ?? 'unknown'; | ||
final slugifiedName = _encodeHashComponent(name.replaceAll(' ', '-')); | ||
fragment.write('$streamId-$slugifiedName'); | ||
case ApiNarrowTopic(): | ||
fragment.write(_encodeHashComponent(element.operand)); | ||
case ApiNarrowDmModern(): | ||
final suffix = element.operand.length >= 3 ? 'group' : 'dm'; | ||
fragment.write('${element.operand.join(',')}-$suffix'); | ||
case ApiNarrowPmWith(): | ||
final suffix = element.operand.length >= 3 ? 'group' : 'pm'; | ||
fragment.write('${element.operand.join(',')}-$suffix'); | ||
case ApiNarrowDm(): | ||
assert(false, 'ApiNarrowDm should have been resolved'); | ||
case ApiNarrowMessageId(): | ||
fragment.write(element.operand.toString()); | ||
} | ||
} | ||
|
||
if (nearMessageId != null) { | ||
fragment.write('/near/$nearMessageId'); | ||
} | ||
|
||
return store.account.realmUrl.replace(fragment: fragment.toString()); | ||
} | ||
|
||
/// An @-mention, like @**Chris Bobbe|13313**. | ||
/// | ||
/// To omit the user ID part ("|13313") whenever the name part is unambiguous, | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
This sounds at first like it's describing what the commit does. (After all, lots of lint config changes are precisely to "prevent[] us from" doing something, making some kind of mistake.)
One way to disambiguate is to use the past tense when describing things that stopped happening with this commit. So "This was preventing us …", and "was triggering".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate commit-message nit: leave out "[nfc]"
This change is indeed NFC from the perspective of our app code, but the prefix already says it's about the linter; and it does change the behavior of the linter.
A "lint [nfc]:" change, by contrast, would be one that's refactoring our lint config itself. These aren't that common, but if you try
git log --oneline --grep 'lint .nfc.:'
in zulip-mobile you'll see a burst of them a few years ago, as our lint config there has a lot more to it.Similarly a test-only change may say "test:", or "foo test:"; and a pure refactor of the tests will say "test [nfc]:" or "foo test [nfc]:". For examples, try the commands
git log --stat -p --grep 'test:'
andgit log --stat -p --grep 'test .nfc.:'
.