Skip to content

local echo (5/n): Create outbox messages on send #1472

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions lib/api/model/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,15 @@ String? tryParseEmojiCodeToUnicode(String emojiCode) {
}
}

/// The topic servers understand to mean "there is no topic".
///
/// This should match
/// https://github.com/zulip/zulip/blob/6.0/zerver/actions/message_edit.py#L940
/// or similar logic at the latest `main`.
// This is hardcoded in the server, and therefore untranslated; that's
// zulip/zulip#3639.
const String kNoTopicTopic = '(no topic)';

/// The name of a Zulip topic.
// TODO(dart): Can we forbid calling Object members on this extension type?
// (The lack of "implements Object" ought to do that, but doesn't.)
Expand Down Expand Up @@ -586,6 +595,30 @@ extension type const TopicName(String _value) {
/// using [canonicalize].
bool isSameAs(TopicName other) => canonicalize() == other.canonicalize();

/// Convert this topic to match how it would appear on a message object from
/// the server, assuming the topic is originally for a send-message request.
///
/// For a client that does not support empty topics,
/// a modern server (FL>=334) would convert "(no topic)" and empty topics to
/// `store.realmEmptyTopicDisplayName`.
///
/// See also: https://zulip.com/api/send-message#parameter-topic
TopicName interpretAsServer({
required int zulipFeatureLevel,
required String? realmEmptyTopicDisplayName,
}) {
if (zulipFeatureLevel < 334) {
assert(_value.isNotEmpty);
return this;
}
if (_value == kNoTopicTopic || _value.isEmpty) {
// TODO(#1250): this assumes that the 'support_empty_topics'
// client_capability is false; update this when we set it to true
return TopicName(realmEmptyTopicDisplayName!);
}
return TopicName(_value);
}
Comment on lines +598 to +620
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's add a // TODO(server-10) for…removing this method, I guess? Or at least simplifying.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is whitespace-trimming also a step in any servers' interpretation of topics? Not that this method has to mirror that logic necessarily. But we'd probably want to explicitly expect (and assert) that that step has already been done when this method is called, otherwise the summary line wouldn't be quite accurate:

  /// Convert this topic to match how it would appear on a message object from
  /// the server, assuming the topic is originally for a send-message request.


TopicName.fromJson(this._value);

String toJson() => apiName;
Expand Down
9 changes: 0 additions & 9 deletions lib/api/route/messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,6 @@ const int kMaxTopicLengthCodePoints = 60;
// https://zulip.com/api/send-message#parameter-content
const int kMaxMessageLengthCodePoints = 10000;

/// The topic servers understand to mean "there is no topic".
///
/// This should match
/// https://github.com/zulip/zulip/blob/6.0/zerver/actions/message_edit.py#L940
/// or similar logic at the latest `main`.
// This is hardcoded in the server, and therefore untranslated; that's
// zulip/zulip#3639.
const String kNoTopicTopic = '(no topic)';

/// https://zulip.com/api/send-message
Future<SendMessageResult> sendMessage(
ApiConnection connection, {
Expand Down
8 changes: 8 additions & 0 deletions lib/model/binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ abstract class ZulipBinding {
/// This wraps [url_launcher.closeInAppWebView].
Future<void> closeInAppWebView();

/// Provides access to the current UTC date and time.
///
/// Outside tests, this just calls [DateTime.timestamp].
DateTime utcNow();

/// Provides access to a new stopwatch.
///
/// Outside tests, this just calls the [Stopwatch] constructor.
Expand Down Expand Up @@ -381,6 +386,9 @@ class LiveZulipBinding extends ZulipBinding {
return url_launcher.closeInAppWebView();
}

@override
DateTime utcNow() => DateTime.timestamp();

@override
Stopwatch stopwatch() => Stopwatch();

Expand Down
Loading