Skip to content

Conversation

@sdjdd
Copy link
Contributor

@sdjdd sdjdd commented Nov 5, 2020

原本未计划在 4.x 版本实现「好友」,想了想还是实现一下吧,毕竟 4.x 在 5.0 发布后的很长一段时间内,仍会是主要使用版本。

之前未完成的实现,放在一起作参考。与其相比:

  • 没有重命名 FriendShipQuery
  • 没有实现特化的 FriendshipRequest Object

JS SDK 双向好友功能内部文档

参考:https://leancloud.atlassian.net/wiki/spaces/PROD/pages/1105854465

申请成为好友

当前登录用户申请成为 Tom 的好友:

AV.Friendship.request("tom's objectId")
  .then(() => {
    console.log('好友请求发送成功');
  })
  .catch((error) => {
    console.error('好友请求发送失败', error);
  });

申请的同时添加属性:

这里模仿了 AV.User#follow 的使用风格

AV.Friendship.request({
  friend: "tom's objectId",
  attributes: {
    group: ['husband'],
  },
});

查询好友申请

如果 Tom 不在线,上线后要查询谁正在添加自己为好友:

const query = new AV.Query('_FriendshipRequest');
query.equalTo('friend', AV.User.current());
query.equalTo('status', 'pending');
query.find().then((requests) => {
  // requests(AV.Object[]) 是所有申请加 Tom 为好友的请求
});

订阅好友申请

当 Tom 上线时,执行以下代码可以订阅好友申请:

const query = new AV.Query('_FriendshipRequest');
query.equalTo('friend', AV.User.current());
query.equalTo('status', 'pending');
query.subscribe().then((subscription) => {
  subscription.on('create', (request) => {
    console.log(`${request.get('user').id} 申请添加我为好友`);
  });
});

订阅当前用户的申请状态变更(被通过、被拒绝):

const query = new AV.Query('_FriendshipRequest');
query.equalTo('user', AV.User.current());
query.subscribe().then((subscription) => {
  subscription.on('update', (request) => {
    const status = request.get('status');
    if (status === 'accepted') {
      console.log(`${request.get('friend').id} 通过了我的好友申请`);
    }
    if (status === 'declined') {
      console.log(`${request.get('friend').id} 拒绝了我的好友申请`);
    }
  });
});

通过、拒绝好友申请

查询后的 requests 数组成员是普通的 AV.Object 。因为不想添加太多特化的 Object ,这里就用 AV.Friendship 类的静态方法处理好友申请,使用起来也相对灵活。

const query = new AV.Query('_FriendshipRequest');
query.equalTo('friend', AV.User.current());
query.equalTo('status', 'pending');
query.find().then((requests) => {
  // 全部接受
  requests.forEach(AV.Friendship.acceptRequest);
  // 或者全部拒绝
  requests.forEach(AV.Friendship.declineRequest);
  // 接受的同时添加属性
  requests.forEach((request) => {
    AV.Friendship.acceptRequest({
      request,
      attributes: {
        group: ['husband'],
      },
    });
  });
});

查询好友

感觉没必要再进行封装。直接使用 AV.Query 还可以 skip、limit、include,非常方便。

const query = new AV.Query('_Followee');
query.equalTo('user', AV.User.current());
query.equalTo('friendStatus', true);
query.find().then((results) => {
  const friends = results.map(result => result.get('followee'));
});

删除好友

使用 unfollow 单向删除与 Tom 的好友关系:

AV.User.current().unfollow("Tom's objectId");

设置自定义属性

const followee = AV.Object.createWithoutData('_Followee', 'ididid');
// 添加属性
followee.set('remark', 'idiot');
// 更新属性
followee.set('group', ['ex']);
// 删除属性
followee.unset('nickname');

@sdjdd sdjdd requested review from leeyeh and nicecui November 5, 2020 08:36
@codecov
Copy link

codecov bot commented Nov 5, 2020

Codecov Report

Merging #626 (243b6d5) into master (ff3db71) will decrease coverage by 0.43%.
The diff coverage is 18.75%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #626      +/-   ##
==========================================
- Coverage   64.24%   63.80%   -0.44%     
==========================================
  Files          38       39       +1     
  Lines        3286     3318      +32     
==========================================
+ Hits         2111     2117       +6     
- Misses       1175     1201      +26     
Impacted Files Coverage Δ
src/user.js 52.86% <0.00%> (-0.74%) ⬇️
src/friendship.js 20.00% <20.00%> (ø)
src/index.js 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ff3db71...243b6d5. Read the comment docs.

@nicecui
Copy link

nicecui commented Nov 6, 2020

// 全部接受
requests.forEach(AV.Friendship.acceptRequest);
// 或者全部拒绝
requests.forEach(AV.Friendship.declineRequest);

静态方法接受或拒绝好奇怪啊,你们真的决定要这么做了吗?

@sdjdd
Copy link
Contributor Author

sdjdd commented Nov 6, 2020

静态方法接受或拒绝好奇怪啊,你们真的决定要这么做了吗?

你是倾向于直接通过请求对象接受、拒绝吗?比如:

const query = new AV.Query('_FriendshipRequest');
query.equalTo('friend', AV.User.current());
query.equalTo('status', 'pending');
query.find().then((requests) => {
  assert(requests.length > 2);
  // 接受
  requests[0].accept();
  // 拒绝
  requests[1].decline();
});

这样也可以,5.0 就这样。但 5.0 有 Class 这个概念,可以很方便的返回特化的 Object 。没有在 4.x 这样实现是我想把实现这个功能所做的改动降到最低,但这种实现方式我没有意见。

@nicecui
Copy link

nicecui commented Nov 6, 2020

你是倾向于直接通过请求对象接受、拒绝吗?

是的。按你们计划的来叭。

@sdjdd sdjdd force-pushed the feat/friendship-2 branch from 903cb28 to 243b6d5 Compare November 19, 2020 09:56
@sdjdd sdjdd merged commit 54400cc into leancloud:master Nov 19, 2020
@sdjdd sdjdd deleted the feat/friendship-2 branch November 20, 2020 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants