feat: status
parent
cf87916b8c
commit
aec1551cb7
|
@ -85,6 +85,50 @@ namespace Storage.Test {
|
|||
Assert.AreEqual(followersAndFollowees.FolloweesCount, 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Order(3)]
|
||||
public async Task Send() {
|
||||
await LCUser.BecomeWithSessionToken(user1.SessionToken);
|
||||
|
||||
// 给粉丝发送状态
|
||||
LCStatus status = new LCStatus {
|
||||
Data = new Dictionary<string, object> {
|
||||
{ "image", "xxx.jpg" },
|
||||
{ "content", "hello, world" }
|
||||
}
|
||||
};
|
||||
await LCStatus.SendToFollowers(status);
|
||||
|
||||
// 给某个用户发送私信
|
||||
LCStatus privateStatus = new LCStatus {
|
||||
Data = new Dictionary<string, object> {
|
||||
{ "image", "xxx.jpg" },
|
||||
{ "content", "hello, game" }
|
||||
}
|
||||
};
|
||||
await LCStatus.SendPrivately(status, user2.ObjectId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Order(4)]
|
||||
public async Task Query() {
|
||||
await LCUser.BecomeWithSessionToken(user2.SessionToken);
|
||||
|
||||
LCStatusCount statusCount = await LCStatus.GetCount(LCStatus.InboxTypeDefault);
|
||||
Assert.Greater(statusCount.Total, 0);
|
||||
LCStatusCount privateCount = await LCStatus.GetCount(LCStatus.InboxTypePrivate);
|
||||
Assert.Greater(privateCount.Total, 0);
|
||||
|
||||
LCStatusQuery query = new LCStatusQuery(LCStatus.InboxTypeDefault);
|
||||
ReadOnlyCollection<LCStatus> statuses = await query.Find();
|
||||
foreach (LCStatus status in statuses) {
|
||||
Assert.AreEqual((status["source"] as LCObject).ObjectId, user1.ObjectId);
|
||||
await status.Delete();
|
||||
}
|
||||
|
||||
await LCStatus.ResetUnreadCount(LCStatus.InboxTypePrivate);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Order(5)]
|
||||
public async Task Unfollow() {
|
||||
|
|
|
@ -136,15 +136,25 @@ namespace LeanCloud.Storage.Internal.Http {
|
|||
throw HandleErrorResponse(response.StatusCode, resultString);
|
||||
}
|
||||
|
||||
public async Task Delete(string path) {
|
||||
string url = await BuildUrl(path);
|
||||
public async Task Delete(string path,
|
||||
Dictionary<string, object> headers = null,
|
||||
object data = null,
|
||||
Dictionary<string, object> queryParams = null) {
|
||||
string url = await BuildUrl(path, queryParams);
|
||||
HttpRequestMessage request = new HttpRequestMessage {
|
||||
RequestUri = new Uri(url),
|
||||
Method = HttpMethod.Delete
|
||||
};
|
||||
await FillHeaders(request.Headers);
|
||||
await FillHeaders(request.Headers, headers);
|
||||
|
||||
LCHttpUtils.PrintRequest(client, request);
|
||||
string content = null;
|
||||
if (data != null) {
|
||||
content = JsonConvert.SerializeObject(data);
|
||||
StringContent requestContent = new StringContent(content);
|
||||
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
request.Content = requestContent;
|
||||
}
|
||||
LCHttpUtils.PrintRequest(client, request, content);
|
||||
HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
request.Dispose();
|
||||
|
||||
|
@ -153,7 +163,7 @@ namespace LeanCloud.Storage.Internal.Http {
|
|||
LCHttpUtils.PrintResponse(response, resultString);
|
||||
|
||||
if (response.IsSuccessStatusCode) {
|
||||
Dictionary<string, object> ret = JsonConvert.DeserializeObject<Dictionary<string, object>>(resultString,
|
||||
_ = JsonConvert.DeserializeObject<Dictionary<string, object>>(resultString,
|
||||
LCJsonConverter.Default);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace LeanCloud {
|
|||
LCObject.RegisterSubclass(LCUser.CLASS_NAME, () => new LCUser());
|
||||
LCObject.RegisterSubclass(LCRole.CLASS_NAME, () => new LCRole());
|
||||
LCObject.RegisterSubclass(LCFile.CLASS_NAME, () => new LCFile());
|
||||
LCObject.RegisterSubclass(LCStatus.CLASS_NAME, () => new LCStatus());
|
||||
LCObject.RegisterSubclass(LCFriendshipRequest.CLASS_NAME, () => new LCFriendshipRequest());
|
||||
|
||||
AppRouter = new LCAppRouter(appId, server);
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using LeanCloud.Storage.Internal.Codec;
|
||||
using LeanCloud.Storage.Internal.Object;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace LeanCloud.Storage {
|
||||
public class LCStatus : LCObject {
|
||||
public const string CLASS_NAME = "_Status";
|
||||
|
||||
/// Public, shown on followees' timeline.
|
||||
public const string InboxTypeDefault = "default";
|
||||
|
||||
/// Private.
|
||||
public const string InboxTypePrivate = "private";
|
||||
|
||||
/// Keys
|
||||
public const string SourceKey = "source";
|
||||
public const string InboxTypeKey = "inboxType";
|
||||
public const string OwnerKey = "owner";
|
||||
public const string MessageIdKey = "messageId";
|
||||
|
||||
public int MessageId {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
public string InboxType {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
private LCQuery query;
|
||||
|
||||
public Dictionary<string, object> Data {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public LCStatus() : base(CLASS_NAME) {
|
||||
InboxType = InboxTypeDefault;
|
||||
Data = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public static async Task<LCStatus> SendToFollowers(LCStatus status) {
|
||||
if (status == null) {
|
||||
throw new ArgumentNullException(nameof(status));
|
||||
}
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
status.Data[SourceKey] = user;
|
||||
|
||||
LCQuery<LCObject> query = new LCQuery<LCObject>("_Follower")
|
||||
.WhereEqualTo("user", user)
|
||||
.Select("follower");
|
||||
status.query = query;
|
||||
|
||||
status.InboxType = InboxTypeDefault;
|
||||
|
||||
return await status.Send();
|
||||
}
|
||||
|
||||
public static async Task<LCStatus> SendPrivately(LCStatus status, string targetId) {
|
||||
if (status == null) {
|
||||
throw new ArgumentNullException(nameof(status));
|
||||
}
|
||||
if (string.IsNullOrEmpty(targetId)) {
|
||||
throw new ArgumentNullException(nameof(targetId));
|
||||
}
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
status.Data[SourceKey] = user;
|
||||
LCQuery<LCObject> query = new LCQuery<LCObject>("_User")
|
||||
.WhereEqualTo("objectId", targetId);
|
||||
status.query = query;
|
||||
|
||||
status.InboxType = InboxTypePrivate;
|
||||
|
||||
return await status.Send();
|
||||
}
|
||||
|
||||
public async Task<LCStatus> Send() {
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
Dictionary<string, object> formData = new Dictionary<string, object> {
|
||||
{ InboxTypeKey, InboxType }
|
||||
};
|
||||
if (Data != null) {
|
||||
formData["data"] = LCEncoder.Encode(Data);
|
||||
}
|
||||
if (query != null) {
|
||||
Dictionary<string, object> queryData = new Dictionary<string, object> {
|
||||
{ "className", query.ClassName }
|
||||
};
|
||||
Dictionary<string, object> ps = query.BuildParams();
|
||||
if (ps.TryGetValue("where", out object whereObj) &&
|
||||
whereObj is string where) {
|
||||
queryData["where"] = JsonConvert.DeserializeObject(where);
|
||||
}
|
||||
if (ps.TryGetValue("keys", out object keys)) {
|
||||
queryData["keys"] = keys;
|
||||
}
|
||||
formData["query"] = queryData;
|
||||
}
|
||||
Dictionary<string, object> response = await LCApplication.HttpClient.Post<Dictionary<string, object>>("statuses",
|
||||
data: formData);
|
||||
LCObjectData objectData = LCObjectData.Decode(response);
|
||||
Merge(objectData);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public new async Task Delete() {
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
LCUser source = (Data[SourceKey] ?? this[SourceKey]) as LCUser;
|
||||
if (source != null && source.ObjectId == user.ObjectId) {
|
||||
await LCApplication.HttpClient.Delete($"statuses/{ObjectId}");
|
||||
} else {
|
||||
Dictionary<string, object> data = new Dictionary<string, object> {
|
||||
{ OwnerKey, JsonConvert.SerializeObject(LCEncoder.Encode(user)) },
|
||||
{ InboxTypeKey, InboxType },
|
||||
{ MessageIdKey, MessageId }
|
||||
};
|
||||
await LCApplication.HttpClient.Delete("subscribe/statuses/inbox", queryParams: data);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<LCStatusCount> GetCount(string inboxType) {
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
Dictionary<string, object> queryParams = new Dictionary<string, object> {
|
||||
{ OwnerKey, JsonConvert.SerializeObject(LCEncoder.Encode(user)) }
|
||||
};
|
||||
if (!string.IsNullOrEmpty(inboxType)) {
|
||||
queryParams[InboxTypeKey] = inboxType;
|
||||
}
|
||||
Dictionary<string, object> response = await LCApplication.HttpClient.Get<Dictionary<string, object>>("subscribe/statuses/count",
|
||||
queryParams: queryParams);
|
||||
LCStatusCount statusCount = new LCStatusCount {
|
||||
Total = (int)response["total"],
|
||||
Unread = (int)response["unread"]
|
||||
};
|
||||
return statusCount;
|
||||
}
|
||||
|
||||
public static async Task ResetUnreadCount(string inboxType = null) {
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
Dictionary<string, object> queryParams = new Dictionary<string, object> {
|
||||
{ OwnerKey, JsonConvert.SerializeObject(LCEncoder.Encode(user)) }
|
||||
};
|
||||
if (!string.IsNullOrEmpty(inboxType)) {
|
||||
queryParams[InboxTypeKey] = inboxType;
|
||||
}
|
||||
await LCApplication.HttpClient.Post<Dictionary<string, object>>("subscribe/statuses/resetUnreadCount",
|
||||
queryParams:queryParams);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace LeanCloud.Storage {
|
||||
public class LCStatusCount {
|
||||
public int Total {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public int Unread {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using LeanCloud.Storage.Internal.Codec;
|
||||
using LeanCloud.Storage.Internal.Object;
|
||||
|
||||
namespace LeanCloud.Storage {
|
||||
public class LCStatusQuery : LCQuery<LCStatus> {
|
||||
public string InboxType {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public int SinceId {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public int MaxId {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public LCStatusQuery(string inboxType = LCStatus.InboxTypeDefault) : base("_Status") {
|
||||
InboxType = inboxType;
|
||||
SinceId = 0;
|
||||
MaxId = 0;
|
||||
}
|
||||
|
||||
public async Task<ReadOnlyCollection<LCStatus>> Find() {
|
||||
LCUser user = await LCUser.GetCurrent();
|
||||
if (user == null) {
|
||||
throw new ArgumentNullException("current user");
|
||||
}
|
||||
|
||||
Dictionary<string, object> queryParams = new Dictionary<string, object> {
|
||||
{ LCStatus.OwnerKey, JsonConvert.SerializeObject(LCEncoder.Encode(user)) },
|
||||
{ LCStatus.InboxTypeKey, InboxType },
|
||||
{ "where", BuildWhere() },
|
||||
{ "sinceId", SinceId },
|
||||
{ "maxId", MaxId },
|
||||
{ "limit", Condition.Limit }
|
||||
};
|
||||
Dictionary<string, object> response = await LCApplication.HttpClient.Get<Dictionary<string, object>>("subscribe/statuses",
|
||||
queryParams: queryParams);
|
||||
List<object> results = response["results"] as List<object>;
|
||||
List<LCStatus> statuses = new List<LCStatus>();
|
||||
foreach (object item in results) {
|
||||
LCObjectData objectData = LCObjectData.Decode(item as IDictionary);
|
||||
LCStatus status = new LCStatus();
|
||||
status.Merge(objectData);
|
||||
status.MessageId = (int)objectData.CustomPropertyDict[LCStatus.MessageIdKey];
|
||||
status.Data = objectData.CustomPropertyDict;
|
||||
status.InboxType = objectData.CustomPropertyDict[LCStatus.InboxTypeKey] as string;
|
||||
statuses.Add(status);
|
||||
}
|
||||
|
||||
return statuses.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue