Commit 2b73dc9c authored by sheteng's avatar sheteng

fixbugs

parent 05829b3f
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="10.4.6.88:5555" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-11-13T05:39:00.572615Z" />
</component>
</project>
\ No newline at end of file
......@@ -3,9 +3,27 @@
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_connect.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_login.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_main.xml" value="0.20153985507246377" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_main2.xml" value="0.27309782608695654" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/activity_main4.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/content_main.xml" value="0.20153985507246377" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/content_main2.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_channel_connect.xml" value="0.338768115942029" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_connect.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_dashboard.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_first.xml" value="0.25" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_group.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_home.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_item_list.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_login.xml" value="0.1" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/fragment_notifications.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/msg_row_item.xml" value="0.3170289855072464" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/parent_item.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/layout/text_row_item.xml" value="0.322463768115942" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/menu/bottom_nav_menu.xml" value="0.33697916666666666" />
<entry key="..\:/project/ccwangluoIm/app/src/main/res/menu/menu_main.xml" value="0.33697916666666666" />
</map>
</option>
</component>
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProtobufLanguageSettings">
<option name="autoConfigEnabled" value="false" />
<option name="importPathEntries">
<list>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/build/generated/res/resValues/debug" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/build/generated/ap_generated_sources/debug/out" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/build/generated/source/proto/debug/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/src/test/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/src/main/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/build/generated/ap_generated_sources/debugUnitTest/out" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/src/androidTest/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/build/generated/source/buildConfig/debug" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/build/generated/ap_generated_sources/debug/out" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/src/main/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/build/generated/source/buildConfig/debug" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/src/androidTest/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/build/generated/res/resValues/debug" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/src/test/java" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/app/src/main/res" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="jar://$APPLICATION_PLUGINS_DIR$/protobuf-editor.jar!/include" />
</ImportPathEntry>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/ccim/src/main/proto" />
</ImportPathEntry>
</list>
</option>
<option name="descriptorPath" value="google/protobuf/descriptor.proto" />
</component>
</project>
\ No newline at end of file
......@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "com.ccwangluo.xiyuan22"
minSdkVersion 16
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
......@@ -32,6 +32,10 @@ android {
}
dependencies {
implementation 'androidx.annotation:annotation:1.2.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.0'
def multidex_version = "2.0.1"
implementation "androidx.multidex:multidex:$multidex_version"
......
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ccwangluo.im">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".App"
......@@ -12,8 +13,17 @@
android:supportsRtl="true"
android:theme="@style/Theme.CcwangluoIm">
<activity
android:name=".MainActivity"
android:name=".MainActivity2"
android:screenOrientation="portrait"
android:exported="false"
android:label="@string/title_activity_main2" /> <!-- <activity -->
<!-- android:name=".ui.login.LoginActivity" -->
<!-- android:exported="false" -->
<!-- android:label="@string/title_activity_login" /> -->
<activity
android:name=".ui.login.LoginActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/Theme.CcwangluoIm.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......
package com.ccwangluo.im;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.NetStatus;
import com.ccwangluo.ccim.data.PushChannelMsgRes;
import com.ccwangluo.ccim.data.PushPrivateMsgRes;
import com.ccwangluo.ccim.data.User;
import com.ccwangluo.ccim.listener.OnPushMsgListener;
import com.ccwangluo.ccim.listener.ResultCallback;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.ActivityMain2Binding;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity2 extends AppCompatActivity {
private LoginViewModel loginViewModel;
private ActivityMain2Binding binding;
private NavController navController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMain2Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_dashboard, R.id.navigation_notifications)
.build();
navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main2);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(binding.navView, navController);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);//添加默认的返回图标
getSupportActionBar().setHomeButtonEnabled(true);
loginViewModel = new ViewModelProvider(this)
.get(LoginViewModel.class);
loginViewModel.getContactList();
CCIMClient.getInstance().registerMessageListener(new OnPushMsgListener() {
@Override
public void pushPrivateMsg(PushPrivateMsgRes msg) {
loginViewModel.addPrivateMsg(msg);
}
@Override
public void pushChannelMsg(PushChannelMsgRes msg) {
loginViewModel.addChannelMsg(msg);
}
@Override
public void pushNewContact(Contact contact) {
loginViewModel.getContactList();
}
@Override
public void pushDeleteContact(Long contactId) {
loginViewModel.getContactList();
}
@Override
public void pushContactNetStatus(Long contactId, NetStatus status) {
loginViewModel.getContactList();
}
@Override
public void pushContactNewReq(User user) {
String[] strings = {user.getUsername()};
AlertDialog alertDialog = new AlertDialog
.Builder(MainActivity2.this)
.setTitle("contact request list 点击验证好友")
.setItems(strings, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CCIMClient.getInstance().checkContactReq(user.getUserId(), true, new ResultCallback() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity2.this, "验证好友发送成功", Toast.LENGTH_SHORT).show();
loginViewModel.getContactList();
}
@Override
public void onFailed(int errorCode) {
Toast.makeText(MainActivity2.this, "验证好友失败 : " + errorCode, Toast.LENGTH_SHORT).show();
}
});
}
})
.create();
alertDialog.show();
}
@Override
public void pushBlockByContact(Long userId) {
loginViewModel.getContactList();
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:// 点击返回图标事件
navController.navigateUp();
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
CCIMClient.getInstance().logout();
}
}
\ No newline at end of file
package com.ccwangluo.im;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.ccwangluo.im.databinding.FragmentSecondBinding;
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecondBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment);
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
\ No newline at end of file
package com.ccwangluo.im.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.ccwangluo.im.R;
import com.ccwangluo.im.listener.ChannelClickListener;
import java.util.List;
public class ChannelAdapter extends BaseAdapter {
private List<Long> dataList;
private Context context;
private ChannelClickListener channelClickListener;
public ChannelAdapter(List<Long> dataList, Context context, ChannelClickListener channelClickListener) {
this.dataList = dataList;
this.context = context;
this.channelClickListener = channelClickListener;
}
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder).
*/
public static class ViewHolder {
public TextView msg_content;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder mHolder;
if (convertView == null) {
mHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.msg_row_item, null, true);
mHolder.msg_content = convertView.findViewById(R.id.msg_content);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
mHolder.msg_content.setText(dataList.get(position).toString());
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
channelClickListener.itemClick(dataList.get(position));
}
});
convertView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
channelClickListener.itemLongClick(dataList.get(position));
return false;
}
});
return convertView;
}
public void refreshData() {
notifyDataSetChanged();
}
}
package com.ccwangluo.im.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.ccwangluo.ccim.data.PushChannelMsgRes;
import com.ccwangluo.im.R;
import java.util.List;
public class ChannelMsgAdapter extends BaseAdapter {
private List<PushChannelMsgRes.MessageDTO> dataList;
private Context context;
public ChannelMsgAdapter(List<PushChannelMsgRes.MessageDTO> dataList, Context context) {
this.dataList = dataList;
this.context = context;
}
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder).
*/
public static class ViewHolder {
public TextView msg_content;
public TextView msg_content_send;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder mHolder;
if (convertView == null) {
mHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.msg_row_item, null, true);
mHolder.msg_content = convertView.findViewById(R.id.msg_content);
mHolder.msg_content_send = convertView.findViewById(R.id.msg_content_send);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
PushChannelMsgRes.MessageDTO messageDTO = dataList.get(position);
mHolder.msg_content.setVisibility(View.VISIBLE);
mHolder.msg_content_send.setVisibility(View.GONE);
mHolder.msg_content.setText(messageDTO.getContent());
return convertView;
}
public void refreshData(){
notifyDataSetChanged();
}
}
package com.ccwangluo.im.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.ccwangluo.im.R;
import java.util.ArrayList;
import java.util.List;
public class ContactGroupAdapter extends RecyclerView.Adapter<ContactGroupAdapter.ViewHolder> {
private List<String> dataList;
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder).
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView contactId;
public TextView contactName;
public ViewHolder(View view) {
super(view);
contactId = (TextView) view.findViewById(R.id.contactId);
contactName = (TextView) view.findViewById(R.id.contactName);
}
}
/**
* Initialize the dataset of the Adapter.
*
* @param dataSet String[] containing the data to populate views to be used
* by RecyclerView.
*/
public ContactGroupAdapter() {
dataList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
dataList.add(String.valueOf(i));
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.text_row_item, viewGroup, false);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.contactId.setText(String.valueOf(dataList.get(position)));
viewHolder.contactName.setText(dataList.get(position));
}
@Override
public int getItemCount() {
return dataList.size();
}
}
package com.ccwangluo.im.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.ccwangluo.ccim.data.PushPrivateMsgRes;
import com.ccwangluo.im.R;
import java.util.List;
public class PrivateMsgAdapter extends BaseAdapter {
private List<PushPrivateMsgRes.MessageDTO> dataList;
private Context context;
public PrivateMsgAdapter(List<PushPrivateMsgRes.MessageDTO> dataList, Context context) {
this.dataList = dataList;
this.context = context;
}
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder).
*/
public static class ViewHolder {
public TextView msg_content;
public TextView msg_content_send;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder mHolder;
if (convertView == null) {
mHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.msg_row_item, null, true);
mHolder.msg_content = convertView.findViewById(R.id.msg_content);
mHolder.msg_content_send = convertView.findViewById(R.id.msg_content_send);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
PushPrivateMsgRes.MessageDTO messageDTO = dataList.get(position);
if (messageDTO.getSenderUserId() != null) {
mHolder.msg_content.setVisibility(View.VISIBLE);
mHolder.msg_content_send.setVisibility(View.GONE);
mHolder.msg_content.setText(messageDTO.getContent());
} else if (messageDTO.getReciveUserId() != null){
mHolder.msg_content.setVisibility(View.GONE);
mHolder.msg_content_send.setVisibility(View.VISIBLE);
mHolder.msg_content_send.setText(messageDTO.getContent());
}
return convertView;
}
public void refreshData(){
notifyDataSetChanged();
}
}
package com.ccwangluo.im.data;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.ContactGroup;
import com.ccwangluo.ccim.data.PushChannelMsgRes;
import com.ccwangluo.ccim.data.PushPrivateMsgRes;
import com.ccwangluo.ccim.listener.ContactsCallBack;
import com.ccwangluo.ccim.listener.OnConnectListener;
import com.ccwangluo.ccim.util.HmacUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class LoginViewModel extends ViewModel {
public MutableLiveData<Boolean> loginState = new MutableLiveData<>();
public MutableLiveData<Collection<Contact>> contactList = new MutableLiveData<>();
public MutableLiveData<Collection<ContactGroup>> contactGroupList = new MutableLiveData<>();
public MutableLiveData<List<PushPrivateMsgRes>> privateMsgList = new MutableLiveData<>();
public MutableLiveData<List<PushChannelMsgRes>> channelMsgList = new MutableLiveData<>();
public MutableLiveData<List<Long>> channelList = new MutableLiveData<>();
public void login(String username, String userId) {
// can be launched in a separate asynchronous job
String appKey = "c981adfde9c4000";
Long id = Long.parseLong(userId);
String extData = "extData";
Long ts = System.currentTimeMillis();
String data = appKey + "&" + id + "&" + username + "&" + extData + "&" + ts +
"&wW7cR31PwJseIoZMOs311nljHpwUmujs";
//sign计算在服务器,本地不要暴露appsecrect
String sign = HmacUtil.stringToSign("wW7cR31PwJseIoZMOs311nljHpwUmujs", data);
CCIMClient.getInstance().initSDK(appKey, username, extData, id, ts, sign, new OnConnectListener() {
@Override
public void onSocketConnection() {
loginState.postValue(true);
}
@Override
public void onSocketDisconnection() {
// loginState.postValue(false);
// System.out.println("链接断开");
}
});
}
public void getContactList() {
CCIMClient.getInstance().getContactList(new ContactsCallBack() {
@Override
public void onSuccess(Collection<Contact> contacts, Collection<ContactGroup> contactGroups) {
contactList.postValue(contacts);
contactGroupList.postValue(contactGroups);
}
});
}
public void addChannelId(long id) {
List<Long> value = channelList.getValue();
if (value == null) {
value = new ArrayList<>();
}
value.add(id);
channelList.postValue(value);
}
public void removeChannelId(long id) {
List<Long> value = channelList.getValue();
if (value == null) {
return;
}
value.remove(id);
channelList.postValue(value);
}
public void addPrivateMsg(PushPrivateMsgRes res) {
List<PushPrivateMsgRes> value = privateMsgList.getValue();
if (value == null) {
value = new ArrayList<>();
}
value.add(res);
privateMsgList.postValue(value);
}
public void addChannelMsg(PushChannelMsgRes res) {
List<PushChannelMsgRes> value = channelMsgList.getValue();
if (value == null) {
value = new ArrayList<>();
}
value.add(res);
channelMsgList.postValue(value);
}
}
\ No newline at end of file
package com.ccwangluo.im.listener;
public interface ChannelClickListener {
void itemClick(Long id);
void itemLongClick(Long id);
}
package com.ccwangluo.im.listener;
import com.ccwangluo.ccim.data.Contact;
public interface OnContactClickLisener {
void onClick(Contact contact);
}
package com.ccwangluo.im.ui.dashboard;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.ContactGroup;
import com.ccwangluo.ccim.data.User;
import com.ccwangluo.ccim.listener.ResultCallback;
import com.ccwangluo.ccim.listener.ResultEventCallback;
import com.ccwangluo.im.R;
import com.ccwangluo.im.adapter.ContactExpandableAdapter;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentDashboardBinding;
import com.ccwangluo.im.listener.OnContactClickLisener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ContactsFragment extends Fragment {
private LoginViewModel loginViewModel;
private FragmentDashboardBinding binding;
private ContactExpandableAdapter contactExpandableAdapter;
private List<Contact> contactList = new ArrayList<>();
private List<ContactGroup> contactGroupList = new ArrayList<>();
private NavController navController;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentDashboardBinding.inflate(inflater, container, false);
View root = binding.getRoot();
loginViewModel =
new ViewModelProvider(getActivity()).get(LoginViewModel.class);
contactExpandableAdapter = new ContactExpandableAdapter(getContext(), contactGroupList, contactList, loginViewModel, new OnContactClickLisener() {
@Override
public void onClick(Contact contact) {
Bundle bundle = new Bundle();
bundle.putSerializable("contact",contact);
navController.navigate(R.id.navigation_connect,bundle);
}
});
binding.contactList.setAdapter(contactExpandableAdapter);
loginViewModel.contactList.observe(getViewLifecycleOwner(), new Observer<Collection<Contact>>() {
@Override
public void onChanged(Collection<Contact> contacts) {
contactList.clear();
contactList.addAll(contacts);
contactExpandableAdapter.reFreshData(contactGroupList,contactList);
}
});
loginViewModel.contactGroupList.observe(getViewLifecycleOwner(), new Observer<Collection<ContactGroup>>() {
@Override
public void onChanged(Collection<ContactGroup> contactGroups) {
contactGroupList.clear();
contactGroupList.addAll(contactGroups);
contactExpandableAdapter.reFreshData(contactGroupList,contactList);
}
});
binding.searchUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final EditText inputServer = new EditText(getContext());
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("username").setIcon(android.R.drawable.ic_dialog_info).setView(inputServer)
.setNegativeButton("Cancel", null);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String userName = inputServer.getText().toString();
CCIMClient.getInstance().searchUser(userName, new ResultEventCallback<List<User>>() {
@Override
public void onSuccess(List<User> users) {
if (users.size() > 0) {
showSearchResultdialog(users);
}
}
});
}
});
builder.show();
}
});
binding.contactReqList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showContactReqList();
}
});
binding.createGroup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final EditText inputServer = new EditText(getContext());
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("groupname").setIcon(android.R.drawable.ic_dialog_info).setView(inputServer)
.setNegativeButton("Cancel", null);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String groupname = inputServer.getText().toString();
CCIMClient.getInstance().createContactGroup(groupname, new ResultEventCallback<Long>() {
@Override
public void onSuccess(Long aLong) {
Toast.makeText(getContext(),"createContactGroup success",Toast.LENGTH_SHORT).show();
loginViewModel.getContactList();
}
});
}
});
builder.show();
}
});
loginViewModel.getContactList();
return root;
}
@Override
public void onResume() {
super.onResume();
navController = Navigation.findNavController(getView());
}
private void showContactReqList() {
CCIMClient.getInstance().getContactReqList(new ResultEventCallback<List<User>>() {
@Override
public void onSuccess(List<User> users) {
if (users.size() > 0) {
String[] strings = new String[users.size()];
for (int i = 0; i < users.size(); i++) {
strings[i] = users.get(i).getUsername();
}
AlertDialog alertDialog = new AlertDialog
.Builder(getContext())
.setTitle("contact request list 点击验证好友")
.setItems(strings, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CCIMClient.getInstance().checkContactReq(users.get(which).getUserId(), true, new ResultCallback() {
@Override
public void onSuccess() {
Toast.makeText(getContext(), "验证好友发送成功", Toast.LENGTH_SHORT).show();
loginViewModel.getContactList();
}
@Override
public void onFailed(int errorCode) {
Toast.makeText(getContext(), "验证好友失败 : " + errorCode, Toast.LENGTH_SHORT).show();
}
});
}
})
.create();
alertDialog.show();
}
}
});
}
public void showSearchResultdialog(List<User> users) {
String[] strings = new String[users.size()];
for (int i = 0; i < users.size(); i++) {
strings[i] = users.get(i).getUsername();
}
AlertDialog alertDialog = new AlertDialog
.Builder(getContext())
.setTitle("userList 点击加好友")
.setItems(strings, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CCIMClient.getInstance().addContact(users.get(which).getUserId(), new ResultCallback() {
@Override
public void onSuccess() {
Toast.makeText(getContext(), "加好友发送成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed(int errorCode) {
Toast.makeText(getContext(), "加好友失败 : " + errorCode, Toast.LENGTH_SHORT).show();
}
});
}
})
.setNegativeButton("关闭", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.create();
alertDialog.show();
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
\ No newline at end of file
package com.ccwangluo.im.ui.login;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.ccwangluo.im.MainActivity2;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.ActivityLoginBinding;
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
private ActivityLoginBinding binding;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
loginViewModel = new ViewModelProvider(this)
.get(LoginViewModel.class);
final EditText usernameEditText = binding.username;
final EditText UserIdEditText = binding.password;
final Button loginButton = binding.login;
final ProgressBar loadingProgressBar = binding.loading;
loginViewModel.loginState.observe(this, new Observer<Boolean>() {
@Override
public void onChanged(Boolean aBoolean) {
loadingProgressBar.setVisibility(View.GONE);
if (aBoolean){
Intent intent = new Intent(LoginActivity.this, MainActivity2.class);
startActivity(intent);
finish();
}
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadingProgressBar.setVisibility(View.VISIBLE);
String username = usernameEditText.getText().toString();
if (TextUtils.isEmpty(username)){
Toast.makeText(LoginActivity.this,"username is empty",Toast.LENGTH_SHORT).show();
return;
}
String id = UserIdEditText.getText().toString();
if (TextUtils.isEmpty(id)){
Toast.makeText(LoginActivity.this,"userid is empty",Toast.LENGTH_SHORT).show();
return;
}
loginViewModel.login(username,id);
}
});
}
}
\ No newline at end of file
package com.ccwangluo.im.ui.login;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentLoginBinding;
/**
*/
public class LoginFragment extends Fragment {
private FragmentLoginBinding binding;
private LoginViewModel loginViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
loginViewModel = new ViewModelProvider(this)
.get(LoginViewModel.class);
final EditText usernameEditText = binding.username;
final EditText UserIdEditText = binding.password;
final Button loginButton = binding.login;
final ProgressBar loadingProgressBar = binding.loading;
loginViewModel.loginState.observe(getViewLifecycleOwner(), new Observer<Boolean>() {
@Override
public void onChanged(Boolean aBoolean) {
loadingProgressBar.setVisibility(View.GONE);
if (aBoolean){
}
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadingProgressBar.setVisibility(View.VISIBLE);
String username = usernameEditText.getText().toString();
if (TextUtils.isEmpty(username)){
Toast.makeText(getContext(),"username is empty",Toast.LENGTH_SHORT).show();
return;
}
String id = UserIdEditText.getText().toString();
if (TextUtils.isEmpty(id)){
Toast.makeText(getContext(),"userid is empty",Toast.LENGTH_SHORT).show();
return;
}
loginViewModel.login(username,id);
}
});
return binding.getRoot();
}
}
\ No newline at end of file
package com.ccwangluo.im.ui.notifications;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.data.PushChannelMsgRes;
import com.ccwangluo.ccim.listener.ResultCallback;
import com.ccwangluo.im.adapter.ChannelMsgAdapter;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentChannelConnectBinding;
import java.util.ArrayList;
import java.util.List;
public class ConnectChannelFragment extends Fragment {
private FragmentChannelConnectBinding binding;
private LoginViewModel loginViewModel;
private ChannelMsgAdapter channelMsgAdapter;
private List<PushChannelMsgRes.MessageDTO> list = new ArrayList<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentChannelConnectBinding.inflate(inflater, container, false);
loginViewModel = new ViewModelProvider(getActivity())
.get(LoginViewModel.class);
channelMsgAdapter = new ChannelMsgAdapter(list,getContext());
binding.msgList.setAdapter(channelMsgAdapter);
long channelId = getArguments().getLong("channelId");
loginViewModel.channelMsgList.observe(getViewLifecycleOwner(), new Observer<List<PushChannelMsgRes>>() {
@Override
public void onChanged(List<PushChannelMsgRes> pushChannelMsgRes) {
list.clear();
for (PushChannelMsgRes pushChannelMsgRe : pushChannelMsgRes) {
if (pushChannelMsgRe.getChannelId() == channelId) {
list.add(pushChannelMsgRe.getMessage());
}
}
channelMsgAdapter.refreshData();
binding.msgList.setSelection(channelMsgAdapter.getCount() - 1);
}
});
binding.sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = binding.sendEdit.getText().toString();
CCIMClient.getInstance().sendChannelMessage(content, channelId, new ResultCallback() {
@Override
public void onSuccess() {
binding.sendEdit.setText("");
PushChannelMsgRes.MessageDTO messageDTO = new PushChannelMsgRes.MessageDTO();
messageDTO.setContent(content);
PushChannelMsgRes pushChannelMsgRes = new PushChannelMsgRes();
pushChannelMsgRes.setMessage(messageDTO);
pushChannelMsgRes.setChannelId(channelId);
loginViewModel.addChannelMsg(pushChannelMsgRes);
Toast.makeText(getContext(),"send Success",Toast.LENGTH_LONG).show();
}
});
}
});
return binding.getRoot();
}
}
\ No newline at end of file
package com.ccwangluo.im.ui.notifications;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.listener.ResultCallback;
import com.ccwangluo.ccim.listener.ResultEventCallback;
import com.ccwangluo.im.R;
import com.ccwangluo.im.adapter.ChannelAdapter;
import com.ccwangluo.im.data.LoginViewModel;
import com.ccwangluo.im.databinding.FragmentNotificationsBinding;
import com.ccwangluo.im.listener.ChannelClickListener;
import java.util.ArrayList;
import java.util.List;
public class NotificationsFragment extends Fragment {
private LoginViewModel loginViewModel;
private FragmentNotificationsBinding binding;
private List<Long> list = new ArrayList<>();
private ChannelAdapter channelAdapter;
private NavController navController;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
loginViewModel =
new ViewModelProvider(getActivity()).get(LoginViewModel.class);
binding = FragmentNotificationsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
channelAdapter = new ChannelAdapter(list, getContext(), new ChannelClickListener() {
@Override
public void itemClick(Long id) {
Bundle bundle = new Bundle();
bundle.putLong("channelId",id);
navController.navigate(R.id.navigation_channel_connect,bundle);
}
@Override
public void itemLongClick(Long id) {
longItemClick(id);
}
});
binding.channelList.setAdapter(channelAdapter);
loginViewModel.channelList.observe(getViewLifecycleOwner(), new Observer<List<Long>>() {
@Override
public void onChanged(List<Long> longs) {
list.clear();
list.addAll(longs);
channelAdapter.notifyDataSetChanged();
}
});
binding.joinChannel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final EditText inputServer = new EditText(getContext());
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("channel id").setIcon(android.R.drawable.ic_dialog_info).setView(inputServer)
.setNegativeButton("Cancel", null);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String channelId = inputServer.getText().toString();
long Id = Long.parseLong(channelId);
CCIMClient.getInstance().joinChannel(Id, new ResultCallback() {
@Override
public void onSuccess() {
Toast.makeText(getContext(), "join success", Toast.LENGTH_SHORT).show();
loginViewModel.addChannelId(Id);
}
});
}
});
builder.show();
}
});
binding.createChannel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final EditText channelName = new EditText(getContext());
channelName.setHint("channel name");
final EditText tagView = new EditText(getContext());
tagView.setHint("tag");
CheckBox checkBox = new CheckBox(getContext());
final EditText userList = new EditText(getContext());
userList.setHint("好友");
LinearLayout linearLayout = new LinearLayout(getContext());
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(channelName);
linearLayout.addView(tagView);
linearLayout.addView(checkBox);
linearLayout.addView(userList);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("create channel").setIcon(android.R.drawable.ic_dialog_info).setView(linearLayout)
.setNegativeButton("Cancel", null);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String name = channelName.getText().toString();
String tag = tagView.getText().toString();
boolean checked = checkBox.isChecked();
String users = userList.getText().toString();
ArrayList<Long> longs = new ArrayList<>();
String[] split = users.split(",");
for (int i = 0; i < split.length; i++) {
longs.add(Long.parseLong(split[i]));
}
CCIMClient.getInstance().createChannel(name, tag, checked, longs, new ResultEventCallback<Long>() {
@Override
public void onSuccess(Long aLong) {
Toast.makeText(getContext(), "create success", Toast.LENGTH_SHORT).show();
}
});
}
});
builder.show();
}
});
return root;
}
private void longItemClick(Long id) {
String[] strings = {"退出频道"};
AlertDialog alertDialog = new AlertDialog
.Builder(getContext())
.setItems(strings, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
CCIMClient.getInstance().exitChannel(id, new ResultCallback() {
@Override
public void onSuccess() {
loginViewModel.removeChannelId(id);
Toast.makeText(getContext(),"退出成功",Toast.LENGTH_SHORT).show();
}
});
break;
}
}
})
.create();
alertDialog.show();
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
@Override
public void onResume() {
super.onResume();
navController = Navigation.findNavController(getView());
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".ui.login.LoginActivity">
<EditText
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="96dp"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/prompt_password"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="16dp"
android:layout_marginBottom="64dp"
android:enabled="false"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password"
app:layout_constraintVertical_bias="0.2" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="64dp"
android:layout_marginBottom="64dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/password"
app:layout_constraintStart_toStartOf="@+id/password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".ui.login.LoginActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="840dp"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="96dp"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/prompt_password"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="16dp"
android:layout_marginBottom="64dp"
android:enabled="false"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password"
app:layout_constraintVertical_bias="0.2" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="64dp"
android:layout_marginBottom="64dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/password"
app:layout_constraintStart_toStartOf="@+id/password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".ui.login.LoginActivity">
<EditText
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="96dp"
android:hint="Username"
android:text="15"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="UserId"
android:text="15"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="16dp"
android:layout_marginBottom="64dp"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password"
app:layout_constraintVertical_bias="0.2" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="64dp"
android:layout_marginBottom="64dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/password"
app:layout_constraintStart_toStartOf="@+id/password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu"/>
<fragment
android:id="@+id/nav_host_fragment_activity_main2"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<ListView
android:id="@+id/msg_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:id="@+id/send_edit"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<ListView
android:id="@+id/msg_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:orientation="horizontal">
<EditText
android:id="@+id/send_edit"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".ui.dashboard.ContactsFragment" >
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<Button
android:id="@+id/search_user"
android:text="搜索好友"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:layout_marginLeft="10dp"
android:id="@+id/contact_req_list"
android:text="联系人申请列表"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:layout_marginLeft="10dp"
android:id="@+id/create_group"
android:text="创建群组"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<ExpandableListView
android:id="@+id/contact_list"
android:layout_weight="0"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
\ No newline at end of file
......@@ -24,7 +24,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="userId"
android:text="101" />
android:text="106" />
<EditText
android:id="@+id/userName"
......@@ -46,7 +46,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="channelId"
android:text="6857982583817506816" />
android:text="1" />
</LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".ui.home.GroupFragment" >
<TextView
android:id="@+id/userId"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/userName"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/create_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="创建群组" />
<Button
android:id="@+id/crate_channel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="创建channel" />
<Button
android:id="@+id/joinChannel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="加入channel" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/item_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:name="com.ccwangluo.im.ui.dashboard.ConnectFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ui.dashboard.ConnectFragment"
tools:listitem="@layout/fragment_item" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<EditText
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="96dp"
android:hint="Username"
android:text="10"
android:inputType="textEmailAddress"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="UserId"
android:text="10"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone"
android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="16dp"
android:layout_marginBottom="64dp"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password"
app:layout_constraintVertical_bias="0.2" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="64dp"
android:layout_marginBottom="64dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/password"
app:layout_constraintStart_toStartOf="@+id/password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:text="创建频道"
android:id="@+id/create_channel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:layout_marginLeft="10dp"
android:text="加入频道"
android:id="@+id/join_channel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<ListView
android:id="@+id/channel_list"
android:layout_width="409dp"
android:layout_height="729dp"
android:layout_weight="1"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_margin="10dp"
android:layout_height="match_parent">
<TextView
android:layout_margin="10dp"
android:id="@+id/msg_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:visibility="gone"
android:layout_margin="10dp"
android:gravity="end"
android:id="@+id/msg_content_send"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:padding="5dp"
android:gravity="center"
android:background="@color/cardview_shadow_start_color"
android:layout_height="50dp">
<TextView
android:id="@+id/tv_parent"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="30dp"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="10dp"
android:background="@color/cardview_shadow_start_color"
android:orientation="vertical"
android:padding="5dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/contactId"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="@color/black" />
<TextView
android:id="@+id/contactName"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="@color/black" />
<TextView
android:id="@+id/netStatus"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="@color/black" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/status"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="@color/black" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_home_black_24dp"
android:title="联系人"/>
<!-- <item-->
<!-- android:id="@+id/navigation_home"-->
<!-- android:icon="@drawable/ic_dashboard_black_24dp"-->
<!-- android:title="我的"/>-->
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="频道"/>
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_dashboard">
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.ccwangluo.im.ui.dashboard.ContactsFragment"
android:label="联系人"
tools:layout="@layout/fragment_dashboard" />
<!-- <fragment-->
<!-- android:id="@+id/navigation_home"-->
<!-- android:name="com.ccwangluo.im.ui.home.GroupFragment"-->
<!-- android:label="群组"-->
<!-- tools:layout="@layout/fragment_group" />-->
<fragment
android:id="@+id/navigation_notifications"
android:name="com.ccwangluo.im.ui.notifications.NotificationsFragment"
android:label="频道"
tools:layout="@layout/fragment_notifications" />
<fragment
android:id="@+id/navigation_connect"
android:name="com.ccwangluo.im.ui.dashboard.ConnectFragment"
android:label="聊天"
app:defaultNavHost="true"
tools:layout="@layout/fragment_connect" />
<fragment
android:id="@+id/navigation_channel_connect"
android:name="com.ccwangluo.im.ui.notifications.ConnectChannelFragment"
android:label="频道聊天"
app:defaultNavHost="true"
tools:layout="@layout/fragment_connect" />
<fragment
android:id="@+id/navigation_login"
android:name="com.ccwangluo.im.ui.login.LoginFragment"
android:label="登录"
app:defaultNavHost="true"
tools:layout="@layout/fragment_connect" />
</navigation>
\ No newline at end of file
<resources>
<dimen name="activity_horizontal_margin">48dp</dimen>
<dimen name="fab_margin">48dp</dimen>
</resources>
\ No newline at end of file
<resources>
<dimen name="activity_horizontal_margin">200dp</dimen>
<dimen name="fab_margin">200dp</dimen>
</resources>
\ No newline at end of file
<resources>
<dimen name="activity_horizontal_margin">48dp</dimen>
<dimen name="fab_margin">48dp</dimen>
</resources>
\ No newline at end of file
<resources>
<dimen name="fab_margin">16dp</dimen>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="text_margin">16dp</dimen>
</resources>
\ No newline at end of file
......@@ -9,4 +9,20 @@
<string name="hello_first_fragment">Hello first fragment</string>
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
<string name="title_activity_login">LoginActivity</string>
<string name="prompt_email">Email</string>
<string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in or register</string>
<string name="action_sign_in_short">Sign in</string>
<string name="welcome">"Welcome !"</string>
<string name="invalid_username">Not a valid username</string>
<string name="invalid_password">Password must be >5 characters</string>
<string name="login_failed">"Login failed"</string>
<string name="title_activity_main2">MainActivity2</string>
<string name="title_home">Home</string>
<string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string>
<string name="title_activity_main">MainActivity</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
\ No newline at end of file
......@@ -65,4 +65,5 @@ dependencies {
implementation 'com.tonystark.android:socket:latest.release'
implementation 'com.tonystark.android:socket-server:latest.release'
implementation 'com.guolindev.permissionx:permissionx:1.6.1'
implementation 'com.google.code.gson:gson:2.8.7'
}
\ No newline at end of file
package com.ccwangluo.ccim.data;
import java.io.Serializable;
public class Contact implements Serializable {
private Long contactUserId;
private String contactUserName;
private Long privateId;
private NetStatus netStatus = NetStatus.NET_STATUS_ONLINE;
private String extData;
private Long contactGroupId = 0L;
private Status status = Status.CONTACT_STATUS_NORMAL;
public Long getContactUserId() {
return contactUserId;
}
public void setContactUserId(Long contactUserId) {
this.contactUserId = contactUserId;
}
public String getContactUserName() {
return contactUserName;
}
public void setContactUserName(String contactUserName) {
this.contactUserName = contactUserName;
}
public Long getPrivateId() {
return privateId;
}
public void setPrivateId(Long privateId) {
this.privateId = privateId;
}
public NetStatus getNetStatus() {
return netStatus;
}
public void setNetStatus(NetStatus netStatus) {
this.netStatus = netStatus;
}
public String getExtData() {
return extData;
}
public void setExtData(String extData) {
this.extData = extData;
}
public Long getContactGroupId() {
return contactGroupId;
}
public void setContactGroupId(Long contactGroupId) {
this.contactGroupId = contactGroupId;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
package com.ccwangluo.ccim.data;
public class ContactGroup {
private Long groupId;
private String name;
public ContactGroup() {
}
public ContactGroup(Long groupId, String name) {
this.groupId = groupId;
this.name = name;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.ccwangluo.ccim.data;
import java.util.List;
public class ContactRequestsRes {
private List<User> requests;
public List<User> getRequests() {
return requests;
}
public void setRequests(List<User> requests) {
this.requests = requests;
}
}
package com.ccwangluo.ccim.data;
public class Header {
private int version;
private int seq;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
}
package com.ccwangluo.ccim.data;
public enum NetStatus {
NET_STATUS_ONLINE,
NET_STATUS_OFFLINE,
UNRECOGNIZED;
}
package com.ccwangluo.ccim.data;
import java.util.List;
public class PullContactsRes {
private List<ContactGroup> contactGroups;
private List<Contact> contacts;
public List<ContactGroup> getContactGroups() {
return contactGroups;
}
public void setContactGroups(List<ContactGroup> contactGroups) {
this.contactGroups = contactGroups;
}
public List<Contact> getContacts() {
return contacts;
}
public void setContacts(List<Contact> contacts) {
this.contacts = contacts;
}
}
package com.ccwangluo.ccim.data;
public class PushChannelMsgRes {
private Long channelId;
private MessageDTO message;
public Long getChannelId() {
return channelId;
}
public void setChannelId(Long channelId) {
this.channelId = channelId;
}
public MessageDTO getMessage() {
return message;
}
public void setMessage(MessageDTO message) {
this.message = message;
}
public static class MessageDTO {
private String msgId;
private String senderUserId;
private String msgSrcType;
private String content;
private String createdDate;
private String modifiedDate;
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getSenderUserId() {
return senderUserId;
}
public void setSenderUserId(String senderUserId) {
this.senderUserId = senderUserId;
}
public String getMsgSrcType() {
return msgSrcType;
}
public void setMsgSrcType(String msgSrcType) {
this.msgSrcType = msgSrcType;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
}
}
package com.ccwangluo.ccim.data;
public class PushPrivateMsgRes {
private MessageDTO message;
public MessageDTO getMessage() {
return message;
}
public void setMessage(MessageDTO message) {
this.message = message;
}
public static class MessageDTO {
private String msgId;
private Long senderUserId;
private String content;
private String createdDate;
private String modifiedDate;
private Long reciveUserId;
public Long getReciveUserId() {
return reciveUserId;
}
public void setReciveUserId(Long reciveUserId) {
this.reciveUserId = reciveUserId;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public Long getSenderUserId() {
return senderUserId;
}
public void setSenderUserId(Long senderUserId) {
this.senderUserId = senderUserId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
}
}
package com.ccwangluo.ccim.data;
import java.util.List;
public class SearchRes {
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
package com.ccwangluo.ccim.data;
public enum Status {
CONTACT_STATUS_NORMAL, // 正常
CONTACT_STATUS_BLACKED, // 被拉黑
CONTACT_STATUS_BLACK_LIST, // 黑名单
CONTACT_STATUS_BID_BLACKED
}
package com.ccwangluo.ccim.data;
public class User {
public User(Long userId, String username) {
this.userId = userId;
this.username = username;
}
private Long userId;
private String username;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.ccwangluo.ccim.listener;
import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.ContactGroup;
import java.util.Collection;
public interface ContactsCallBack {
void onSuccess(Collection<Contact> contacts, Collection<ContactGroup> contactGroups);
default void onFailed(int errorCode){};
}
......@@ -5,6 +5,10 @@ import com.xuhao.didi.core.pojo.OriginalData;
public interface MessageListener {
default void onServerConnect(){
}
default void onServerDisConnect(){
}
void onMessageListener(OriginalData data);
}
package com.ccwangluo.ccim.listener;
import com.ccwangluo.ccim.data.Contact;
import com.ccwangluo.ccim.data.NetStatus;
import com.ccwangluo.ccim.data.PushChannelMsgRes;
import com.ccwangluo.ccim.data.PushPrivateMsgRes;
import com.ccwangluo.ccim.data.User;
public interface OnPushMsgListener {
void pushPrivateMsg(PushPrivateMsgRes msg);
void pushChannelMsg(PushChannelMsgRes msg);
void pushNewContact(Contact contact);
void pushDeleteContact(Long contactId);
void pushContactNetStatus(Long contactId,NetStatus status);
void pushContactNewReq(User user);
void pushBlockByContact(Long userId);
}
......@@ -18,7 +18,7 @@ public class CallBackManager<T> {
//设置60秒超时
new Handler(Looper.getMainLooper()).postDelayed(() -> {
ResultEventCallback<T> callBack = getCallBack(id);
if (callBack != null){
if (callBack != null && id != 0){
removeCallBack(id);
callBack.onFailed(999);
}
......
......@@ -9,13 +9,16 @@ public class MyIReaderProtocol implements IReaderProtocol {
public int getHeaderLength() {
return 4;
}
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
@Override
public int getBodyLength(byte[] header, ByteOrder byteOrder) {
int value = header[3];
value |= header[2] << 8;
value |= header[1] << 16;
value |= header[0] << 24;
int value = toUnsignedInt(header[3]);
value |= toUnsignedInt((byte) (header[2] << 8));
value |= toUnsignedInt((byte) (header[1] << 16));
value |= toUnsignedInt((byte) (header[0] << 24));
return value;
}
}
......@@ -4,6 +4,7 @@ package ccim.protocol;
import "channel.proto";
import "common.proto";
import "contact.proto";
import "message.proto";
import "push.proto";
......@@ -17,11 +18,11 @@ message ChatRequestMessage {
AddContactRequest add_contact_req = 5; // 添加联系人
ContactRequestsRequest contact_requests_req = 6; // 联系人申请列表
CheckContactReqRequest check_contact_req_req = 7; // 验证联系人申请
CreateContactGroupRequest create_contact_group_req = 8; // 创建联系人群
MoveContactGroupRequest move_contact_group_req = 9; // 移动联系人所在群
DeleteContactRequest delete_contact_req = 10; // 删除联系人
BlockContactRequest block_contact_req = 11; // 联系人拉入黑名单
ReportIllegalUserRequest report_illegal_user_req = 12; // 举报违规用户
CreateContactGroupRequest create_contact_group_req = 8; // 创建联系人
MoveContactGroupRequest move_contact_group_req = 9; // 移动联系人所在
DeleteContactGroupRequest delete_contact_group_req = 10; // 删除联系人组
DeleteContactRequest delete_contact_req = 11; // 删除联系人
BlockContactRequest block_contact_req = 12; // 联系人拉入黑名单
PullOfflineMessageRequest pull_offline_msg_req = 13; // 拉取离线消息
CreateChannelRequest create_channel_req = 21; // 创建频道
......@@ -29,14 +30,16 @@ message ChatRequestMessage {
RemoveMemberRequest remove_member_req = 23; // 移除成员
ExitChannelRequest exit_channel_req = 24; // 退出频道
ReportIllegalUserRequest report_illegal_user_req = 31; // 举报违规用户
SendMessageRequest send_msg_req = 42; // 发送消息
SendChannelMessageRequest send_channel_msg_req = 43; // 发送频道消息
PushPrivateMessageAckRequest push_private_msg_ack_req = 61; // 推送私人消息成功ack
PushChannelMessageAckRequest push_channel_msg_ack_req = 62; // 推送频道消息ack
HeartbeatRequest heartbeat_req = 100;
ConnectionStateAckRequest connection_state_ack_req = 101;
HeartbeatRequest heartbeat_req = 100; // 作用于登录返回的心跳间隔heartbeat_interval
ConnectionStateAckRequest connection_state_ack_req = 101; // 服务端主动返回一个ConnectionStateResponse时客户端必须返回ConnectionStateAckRequest
}
};
......@@ -52,22 +55,30 @@ message ChatResponseMessage {
CheckContactReqResponse check_contact_req_res = 7;
CreateContactGroupResponse create_contact_group_res = 8;
MoveContactGroupResponse move_contact_group_res = 9;
DeleteContactResponse delete_contact_res = 10;
BlockContactResponse block_contact_res = 11;
PullOfflineMessageResponse pull_offline_msg_res = 12;
DeleteContactGroupResponse delete_contact_group_res = 10;
DeleteContactResponse delete_contact_res = 11;
BlockContactResponse block_contact_res = 12;
PullOfflineMessageResponse pull_offline_msg_res = 13;
CreateChannelResponse create_channel_res = 21;
JoinChannelResponse join_channel_res = 22;
RemoveMemberResponse remove_member_res = 23;
ExitChannelResponse exit_channel_res = 24;
ReportIllegalUserResponse report_illegal_user_res = 41;
SendMessageResponse send_msg_res = 42;
SendChannelMessageResponse send_channel_msg_res = 43;
ReportIllegalUserResponse report_illegal_user_res = 31;
SendMessageResponse send_msg_res = 41;
SendChannelMessageResponse send_channel_msg_res = 42;
PushPrivateMessageResponse push_private_msg_res = 61;
PushChannelMessageResponse push_channel_msg_res = 62;
PushContactDeleteMeResponse push_contact_delete_me_res = 71; // 推送联系人删除了我
PushNewContactResponse push_new_contact_res = 72; // 推送有新的联系人
PushContactNetStatusResponse push_contact_net_status_res = 73; // 推送联系人网络状态
PushContactNewReqResponse push_contact_new_req_res = 74; // 推送新的好友申请
PushBlockedByContactResponse push_blocked_by_contact_res = 75; // 推送被联系人拉黑
HeartbeatResponse heartbeat_res = 100;
ConnectionStateResponse connection_state_res = 101;
}
......@@ -97,25 +108,6 @@ message PullContactsResponse {
int64 group_id = 1; // 群组id
string name = 2; // 群组名称
}
message Contact {
enum Status {
NORMAL = 0; // 正常
MUTED = 1; // 拒绝接收消息
BLACK_LIST = 2; // 黑名单
}
enum NetStatus {
ONLINE = 0;
OFFLINE = 1;
}
int64 contact_user_id = 1; // 联系人用户id
string contact_user_name = 2; // 联系人用户名字
int64 contact_group_id = 3; // 联系人群组id
int64 private_id = 4; // 私聊对话id
int64 read_msg_id = 5; // 已读消息id
Status status = 6; // 联系人状态
NetStatus net_status = 7; // 网络状态
string ext_data = 8; // 扩展数据
}
message Channel {
int64 channel_id = 1;
int64 app_id = 2;
......@@ -127,7 +119,6 @@ message PullContactsResponse {
}
repeated ContactGroup contact_groups = 2; // 联系人群组列表
repeated Contact contacts = 3; // 联系人列表
// repeated Group groups = 4; // 群组
repeated Channel channels = 4; // 频道
}
......@@ -147,25 +138,10 @@ message AddContactRequest {
int64 user_id = 1;
}
message AddContactResponse {
enum AddResult {
SUCCESS = 0;
ALREADY_SENT = 1;
NO_AUTHORITY = 2;
ALREADY_CONTACT = 3;
ACCEPT_REQ = 4; // 接受对方的好友申请(对方已经发送申请,自己不必申请直接同意)
}
AddResult result = 1;
}
message ContactRequestsRequest {}
message ContactRequestsResponse {
message ContactRequest {
int64 user_id = 1;
string username = 2;
}
repeated ContactRequest requests = 1;
repeated ContactReqData requests = 1;
}
message CheckContactReqRequest {
......@@ -173,7 +149,9 @@ message CheckContactReqRequest {
int64 req_user_id = 2;
}
message CheckContactReqResponse {}
message CheckContactReqResponse {
Contact new_contact = 1;
}
message CreateContactGroupRequest {
string name = 1;
......@@ -198,14 +176,6 @@ message DeleteContactRequest {
message DeleteContactResponse {
}
message BlockContactRequest {
int64 contact_user_id = 1;
bool mute = 2;
}
message BlockContactResponse {
}
message ReportIllegalUserRequest {
int64 illegal_user_id = 1;
string title = 2;
......
......@@ -16,6 +16,7 @@ enum StatusCode {
STATUS_CODE_INVALID_APP_KEY = 20003; // 无效app_key
STATUS_CODE_SIGN_EXPIRED = 20004; // 签名过期
STATUS_CODE_INVALID_SIGN = 20005; // 无效签名
STATUS_CODE_EXT_DATA_TOO_LARGE = 20006; // 扩展数据过大
// CHAT_SERVICE_ERROR = 30000;
STATUS_CODE_CHECK_CONTACT_UPDATED_ERROR = 30001; // 好友请求已同意或拒绝
......
syntax = "proto3";
package ccim.protocol;
enum NetStatus {
NET_STATUS_ONLINE = 0;
NET_STATUS_OFFLINE = 1;
}
enum ContactStatus {
CONTACT_STATUS_NORMAL = 0; // 正常
CONTACT_STATUS_BLACKED = 1; // 被拉黑
CONTACT_STATUS_BLACK_LIST = 2; // 黑名单
CONTACT_STATUS_BID_BLACKED = 3; // 双向拉黑
}
message Contact {
int64 contact_user_id = 1; // 联系人用户id
string contact_user_name = 2; // 联系人用户名字
int64 contact_group_id = 3; // 联系人群组id
int64 private_id = 4; // 私聊对话id
int64 read_msg_id = 5; // 已读消息id
ContactStatus status = 6; // 联系人状态
NetStatus net_status = 7; // 网络状态
string ext_data = 8; // 扩展数据
}
/**
* 联系人申请
*/
message ContactReqData {
int64 user_id = 1;
string username = 2;
}
message AddContactResponse {
enum AddResult {
SUCCESS = 0;
ALREADY_SENT = 1;
NO_AUTHORITY = 2;
ALREADY_CONTACT = 3;
ACCEPT_REQ = 4; // 接受对方的好友申请(对方已经发送申请,自己不必申请直接同意)
}
AddResult result = 1;
Contact new_contact = 2;
}
message BlockContactRequest {
int64 contact_user_id = 1;
}
message BlockContactResponse {
ContactStatus contact_status = 1;
}
message DeleteContactGroupRequest {
int64 contact_group_id = 1;
}
message DeleteContactGroupResponse {}
\ No newline at end of file
......@@ -2,6 +2,7 @@ syntax = "proto3";
package ccim.protocol;
import "contact.proto";
import "message_spec.proto";
message PushPrivateMessageResponse {
......@@ -22,3 +23,25 @@ message PushChannelMessageAckRequest {
int64 msg_id = 1;
int64 channel_id = 2;
}
message PushContactDeleteMeResponse {
int64 contact_user_id = 1;
}
message PushNewContactResponse {
Contact contact = 1;
}
message PushContactNetStatusResponse {
int64 contact_user_id = 1;
NetStatus net_status = 2;
}
message PushContactNewReqResponse {
ContactReqData contact_new_req = 1;
}
message PushBlockedByContactResponse {
int64 contact_user_id = 1;
ContactStatus contact_status = 2;
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment