Skip to content

Commit a023bc7

Browse files
committed
api: Add updatePresence
1 parent 66b648a commit a023bc7

File tree

4 files changed

+108
-1
lines changed

4 files changed

+108
-1
lines changed

lib/api/model/model.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class PerUserPresence {
350350
Map<String, dynamic> toJson() => _$PerUserPresenceToJson(this);
351351
}
352352

353-
/// As in [PerClientPresence.status].
353+
/// As in [PerClientPresence.status] and [updatePresence].
354354
@JsonEnum(fieldRename: FieldRename.snake, alwaysCreate: true)
355355
enum PresenceStatus {
356356
active,

lib/api/route/users.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:json_annotation/json_annotation.dart';
22

33
import '../core.dart';
4+
import '../model/model.dart';
45

56
part 'users.g.dart';
67

@@ -32,3 +33,49 @@ class GetOwnUserResult {
3233

3334
Map<String, dynamic> toJson() => _$GetOwnUserResultToJson(this);
3435
}
36+
37+
/// https://zulip.com/api/update-presence
38+
///
39+
/// Passes true for `slim_presence` to avoid getting an ancient data format
40+
/// in the response.
41+
// TODO(#1611) Passing `slim_presence` is the old, deprecated way to avoid
42+
// getting an ancient data format. Pass `last_update_id` to new servers to get
43+
// that effect (make lastUpdateId required?) and update the dartdoc.
44+
// (Passing `slim_presence`, for now, shouldn't break things, but we'd like to
45+
// stop; see discussion:
46+
// https://chat.zulip.org/#narrow/channel/378-api-design/topic/presence.20rewrite/near/2201035 )
47+
Future<UpdatePresenceResult> updatePresence(ApiConnection connection, {
48+
int? lastUpdateId,
49+
int? historyLimitDays,
50+
bool? newUserInput,
51+
bool? pingOnly,
52+
required PresenceStatus status,
53+
}) {
54+
return connection.post('updatePresence', UpdatePresenceResult.fromJson, 'users/me/presence', {
55+
if (lastUpdateId != null) 'last_update_id': lastUpdateId,
56+
if (historyLimitDays != null) 'history_limit_days': historyLimitDays,
57+
if (newUserInput != null) 'new_user_input': newUserInput,
58+
if (pingOnly != null) 'ping_only': pingOnly,
59+
'status': RawParameter(status.toJson()),
60+
'slim_presence': true,
61+
});
62+
}
63+
64+
@JsonSerializable(fieldRename: FieldRename.snake)
65+
class UpdatePresenceResult {
66+
final int? presenceLastUpdateId; // TODO(server-9.0) new in FL 263
67+
final double? serverTimestamp; // 1656958539.6287155 in the example response
68+
final Map<int, PerUserPresence>? presences;
69+
// final bool zephyrMirrorActive; // deprecated, ignore
70+
71+
UpdatePresenceResult({
72+
required this.presenceLastUpdateId,
73+
required this.serverTimestamp,
74+
required this.presences,
75+
});
76+
77+
factory UpdatePresenceResult.fromJson(Map<String, dynamic> json) =>
78+
_$UpdatePresenceResultFromJson(json);
79+
80+
Map<String, dynamic> toJson() => _$UpdatePresenceResultToJson(this);
81+
}

lib/api/route/users.g.dart

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/api/route/users_test.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:checks/checks.dart';
2+
import 'package:http/http.dart' as http;
3+
import 'package:flutter_test/flutter_test.dart';
4+
import 'package:zulip/api/model/model.dart';
5+
import 'package:zulip/api/route/users.dart';
6+
7+
import '../../stdlib_checks.dart';
8+
import '../fake_api.dart';
9+
10+
void main() {
11+
test('smoke updatePresence', () {
12+
return FakeApiConnection.with_((connection) async {
13+
final response = UpdatePresenceResult(
14+
presenceLastUpdateId: -1,
15+
serverTimestamp: 1656958539.6287155,
16+
presences: {},
17+
);
18+
connection.prepare(json: response.toJson());
19+
await updatePresence(connection,
20+
lastUpdateId: -1,
21+
historyLimitDays: 21,
22+
newUserInput: false,
23+
pingOnly: false,
24+
status: PresenceStatus.active,
25+
);
26+
check(connection.takeRequests()).single.isA<http.Request>()
27+
..method.equals('POST')
28+
..url.path.equals('/api/v1/users/me/presence')
29+
..bodyFields.deepEquals({
30+
'last_update_id': '-1',
31+
'history_limit_days': '21',
32+
'new_user_input': 'false',
33+
'ping_only': 'false',
34+
'status': 'active',
35+
'slim_presence': 'true',
36+
});
37+
});
38+
});
39+
}

0 commit comments

Comments
 (0)