leancloud / LeanCloudChatKit-Android

95 stars 33 forks source link

ProfileProvider 接口 #1

Closed daweibayu closed 8 years ago

daweibayu commented 8 years ago

暴露出来设置 provider 的接口

public class ProfileProviderManager {

  private static ProfileProvider profileProvider;

  public static void setProfileProvider(ProfileProvider provider) {
    profileProvider = provider;
  }

用户需要自己实现接口

public interface ProfileProvider {

    // 获取自己信息
    public UserProfile getSelf();

    // 获取指定 id 的用户信息
    public void getFriend(String userId, FetchUserCallBack callBack);

    // 获取指定 id list 的用户信息
    public void getFriends(List<String> list, FetchUserCallBack callBack);

    // 分页获取用户信息
    public void getFriends(int skip, int limit, FetchUserCallBack callBack);
}

CallBack

public interface FetchUserCallBack {
    public void done(List<UserProfile> userList, Exception e);
}

UserProfile 的相关属性

public class UserProfile {
    String userId;
    String avatarUrl;
    String name;
}

以上是需要开发者知道的接口,你们先看一下是否合适 @sunng87 @wujun4code @jwfing @ChenYilong @lbt05 @ylgrgyq

jwfing commented 8 years ago

ProfileProviderManager 这个类存在的意义是什么?

jwfing commented 8 years ago

ProfileProvider 这个类里面:

获取指定 id 的用户信息

这个函数的名字为什么叫 getFriend ?感觉这个类里面所有的操作都可以归结为一个函数:

void getProfile(List<String> userIds, FetchUserCallback cb);
jwfing commented 8 years ago

另外还有一点,你对外公开的还有哪些类? 可以这样看,如果我是用户,我现在要使用这个 SDK,那么我需要依赖哪些类,调用的时序是什么样子,才能使用聊天这个功能?如果能把这个问题梳理清楚,那么涉及到的类,就是我们的对外接口了。

daweibayu commented 8 years ago

ProfileProviderManager 的作用就是让用户设置 Provider,不然 LeanCloudIMKit 没法知道用户的 Provider 是什么。

用户需要做的就是两步

  1. 实现一个类实现接口
public class CustomUserProvider implements ProfileProvider {

  @Override
  public UserProfile getSelf() {
    ...
  }

  @Override
  public void getFriend(String userId, FetchUserCallBack callBack) {
    ...
  }

  @Override
  public void getFriends(List<String> list, FetchUserCallBack callBack) {
    ...
  }

  @Override
  public void getFriends(int skip, int limit, FetchUserCallBack callBack) {
    ...
  }
}
  1. 设置 provider
ProfileProviderManager.setProfileProvider(new CustomUserProvider());

涉及到的类就是上边列出来的那四个


关于 getFriend 可以合并成两个函数,分页的那个还是需要有的

public void getProfile(List<String> list, FetchUserCallBack callBack);
public void getProfile(int skip, int limit, FetchUserCallBack callBack);
jwfing commented 8 years ago

我还是没看明白用户用这四个类,如何可以聊起来。。。

wrshi commented 8 years ago

我觉得我看明白了。。。(然而并不一定(:з」∠)

我们实现聊天功能本身的话,所需的信息其实只有clientId,username和avatar等是展示UI用的。这三个信息对应的UserProfile类是可以和用户自己的用户体系直接对接的,不需要多余的操作。

这里面最核心的类是profileProvider,是需要用户自己实现一下。由于我们功能方面只需要clientId,其他的信息由用户通过实现这个类来提供,所谓provider就是这个意思。

关于如何聊起来,我的理解是,用户提供完provider以后就什么都不用做了。我们拿到用户的provider,就可以获得selfId, contactIdList,有这些Id我们就已经可以建立相应的聊天链接进行对话了。然后UI方面,通过provider的getSelf,getFriend等方法,获取头像等其他信息进行展示。

2016-01-26 23:32 GMT+08:00 jfeng notifications@github.com:

我还是没看明白用户用这四个类,如何可以聊起来。。。

— Reply to this email directly or view it on GitHub https://github.com/leancloud/LeanCloudIMKit/issues/1#issuecomment-175079690 .

sunng87 commented 8 years ago

@jwfing 我觉得 @wrshi 说得没问题,这个脚手架默认不需要用户接触任何跟聊天相关的东西,只需要和自己的用户系统结合就可以了,所有聊天相关的都封装在内部。有点类似 web 上的那种第三方评论系统等等,是一个 saas 风格的东西。

daweibayu commented 8 years ago

应该主要包含以下几个页面

以上页面均在 LeanCloudIMKit 里边已经完成。用户只需要把他的用户体系设置过来就可以了,剩下的都是 LeanCloudIMKit 完成了的。

至于样式、图片、背景、聊天气泡、actionbar颜色等,均可以通过资源覆盖的方式去做(这样不用改动 LeanCloudIMKit 的任何代码)。

daweibayu commented 8 years ago

UI 相关

1、ConversationFragment 作用:展示所有 conversation list 的 fragment 参数:无 函数:updateFragment() 主动刷新Fragment

2、ContactFragment 作用:联系人的 fragment 参数:无 函数:updateFragment() 主动刷新Fragment

3、PersonalProfileFragment 作用:登陆者本人详情的 fragment 参数:无 函数:updateFragment() 主动刷新Fragment

4、MainActivity 作用:包含 ConversationFragment、ContactFragment、PersonalProfileFragment

5、ChatActivity 作用:聊天页面 参数:Constants.MEMBER_ID、Constants.CONVERSATION_ID(二选一即可) Action:Constants.AVATAR_CLICK_EVENT(头像点击事件) Action:Constants.CONVERSATION_DETAIL_CLICK_EVENT(回话详情点击事件)

6、ConversationDetailActivity 作用:会话详情页,展示会话的具体成员,有退出会话、删除成员等操作 参数:Constants.CONVERSATION_ID

7、ConversationAddMembersActivity 作用:给 conversation 添加成员 参数:Constants.CONVERSATION_ID 如有改变:会返回 Activity.RESULT_OK,其他页面可以根据返回值判断是否更新 UI

8、ProfileActivity 作用:个人详情页(用户的好友等) 参数:Constants.MEMBER_ID

ChatManager

  1. getInstance() 单例
  2. init(Context, appId,appKey) 备注:之所以不直接用 AVOSCloud.initialize 是因为需要初始话的东西还有很多,索性全放一个函数里边,也不让他知道具体里边细节,想看细节就去看代码
  3. setProfileProvider(ProfileProvider) 备注:原有的 ProfileProviderManager 可以干掉了
  4. open(Callback) 备注:open 成功后直接跳转到 MainActivity 就可以了,然后就进入到 LeancloudIMKit 里边了

以上函数依次调用即可

其他

jwfing commented 8 years ago

@wrshi @sunng87 在只有一个 ProfileProvider 的情况下,你们能说明一下怎么进入聊天界面吗?什么时候进入聊天界面呢?

jwfing commented 8 years ago

我们的目标用户就是懂球帝、链家(LeanCloud 用户),汽车之家、百姓网(融云用户),节操精选、跟谁学(环信客户)这样的用户,我们希望让他们可以非常简单的集成我们的 IM 服务。他们一般都有自己的帐户系统,有自己的联系人页面,有自己的 mainActivity。。。我们在 IMKit 里面只提供最基本的模块就好了。所以:

jwfing commented 8 years ago

ConversationFragment,这个类用来展示所有的 conversation list,这里其实多种情况:

我们支持的是哪一种?对于每一种可能都还要区分单聊、群聊(这其实是业务层面的概念),因为单聊一般显示对方的用户名,群聊则一般显示群聊名字或者参与者名字,还有就是这个 list 的排序规则,可能也会有很多不同需求,所以我的意见是这个类放到 app 里面去实现为好。

wrshi commented 8 years ago

@jwfing 什么时候进入聊天界面:在用户点击conversation list里的某个条目的时候。 这里conversation list按照什么顺序去展示,包括展示什么,我们可以都不去管,或者我们放到demo里去给一个比较理想的实现例子(比如按照微信的逻辑去呈现),这里我们就假定用户来提供这个内容,提供一个Array。 怎么进入聊天界面:根据李伟给的接口,当前用户的Id由ProfileProvider.getSelf.userId拿到,需要对话的用户Id由点击的条目里直接拿到(也就是Array里的一个元素,UserProfile里有用户提供给我们的userId),据此我们调用createConversation,并将此conversation对象传递给下个界面(即聊天界面),此时聊天开始。

sunng87 commented 8 years ago

@jwfing 进入聊天界面的话应该就是一个 startActivity,然后传一些参数,这个 activity 的名字是我们固定的 严格的说这个也算是用户接口吧,不过是固定的,不需要用户实现什么

比如在百姓网的信息发布界面上有一个”跟他联系“按钮,点了这个按钮之后就调用 startActivity(...) 到达了聊天页面。

对话列表也是一个类似的界面,可能用户会把入口放在导航的地方,总之任意的地方 startActivity 就可以进去了。

conversation 列表因为也涉及到操作我们的 API,比如获得每个对话的最后一条消息,显示没有打开的消息数量,这部分对用户来说也比较复杂而且是必需,所以我建议包含一个至少是基础的版本进来。

我个人建议倒是 chat 的 UI,里面的事件可以鼓励用户 fork 我们的库,修改我们的代码实现。这部分细节非常琐碎,设计成接口非常复杂,用户还有理解的成本,不然直接给他代码允许他随意修改。

jwfing commented 8 years ago

@sunng87 @wrshi 我们现在讨论确定的对外接口,需要达到这个程度:我看到这些接口,就知道怎么用了,然后,我可以去写开发指南了。所以,startActivity 这种函数以及需要固定下来的 Activity 名字(包括要传给它的参数)都是需要列出来的。 我们这个库的所有代码都将会是开源的。让别人直接来改你的代码,其实对自身要求是很高的,你的代码需要逻辑清晰、层次清楚、代码风格良好,所以我们内部还是抽象出这些接口,然后配上默认的实现为好,这样他有默认的可用,也知道要改的话集中修改什么地方。如果我们都不能把这些可以扩展的地方抽取出来,是有很大的概率把代码写成一团乱麻的。。。

wrshi commented 8 years ago

@jwfing 那就先确定要做什么页面,每个页面要做什么行为,然后把接口都列出来看一下吧,就像李伟那样。像activity名字之类的,列出来以后再改。 UI方面是不是让别人来改的问题,我想这取决于用户自己的需求,看他要改多深了。我的个人建议是留一些比较基本的修改接口,要想改更大就只能自己来改了,不可能把每个UI细节都用接口照顾到。另外不管是不是让别人来直接改,我们不是都应该把代码写很好吗....(:з」∠)

lbt05 commented 8 years ago

反过来做吧,能不能对着一个完整的应用,大家去拆。 比如用户系统这里我想要可定制化,然后给一个DefaultAVUserProvider之类的 activity之间的交互想要定制化?(这个太难太碎了) 朋友圈消息,给好友点攒这种是排除在基础IM应用的系统边界以外的就扔掉。

sunng87 commented 8 years ago

我这里没什么问题了,用户接口主要就是:两个关键 activity 的名字需要指定,其中 chat ui 还要接受一个 userId 或者一个明确的 convId,conversation 列表那个不需要任何的参数;用户需要实现一个获取 user profile 的接口,传入一组 user id 返回一组 user profile。其他就没有了。

@wrshi iOS 应该也可以实现类似的接口吧?

我的思路是这个脚手架做完之后,我们对着 github 的 user api 做一个实现,从而实现一个基于 github 用户系统的聊天应用(或者说是给一个 github 应用增加聊天的功能)

wrshi commented 8 years ago

@sunng87 恩类似的接口当然可以。具体什么形式实现的话,请宜龙和天勇来确定好啦。

daweibayu commented 8 years ago
  1. 关于样式相关的(比如颜色、背景、点击态)等都是通过样式覆盖的方式处理,不添加任何接口(如果添加接口就太细了)。
  2. 输入框也不支持扩展了吧,如果想添加自己逻辑就去直接 copy 代码吧。
  3. android 这边的头像点击事件、以及详情事件都是通过 Intent,也不需要接口,这个稍后我 Intent 参数补充一下。
daweibayu commented 8 years ago

ProfileProvider 相关接口

public interface ProfileProvider {
    // 获取指定 id list 的用户信息
    public void getProfiles(List<String> list, FetchUserCallBack callBack);
}

CallBack

public interface FetchUserCallBack {
    public void done(List<UserProfile> userList, Exception e);
}

UserProfile 的相关属性

public class UserProfile {
    String userId;
    String avatarUrl;
    String name;
}