This commit is contained in:
Paul Schaub 2019-06-23 02:34:14 +02:00
parent 5bd7866582
commit e7eb6ff9e6
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
38 changed files with 456 additions and 40 deletions

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/opt/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/editor/ic_attach_file_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_attach_file_white_24dp" />
<entry key="sourceFile" value="$USER_HOME$" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -0,0 +1,5 @@
package org.mercury_im.messenger.handler;
public class AvatarHandler {
}

View File

@ -2,15 +2,22 @@ package org.mercury_im.messenger.handler;
import android.util.Log;
import androidx.room.Transaction;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smackx.vcardtemp.VCardManager;
import org.jivesoftware.smackx.vcardtemp.packet.VCard;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
import org.mercury_im.messenger.persistence.room.dao.EntityDao;
import org.mercury_im.messenger.persistence.room.model.RoomContactModel;
import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
import org.mercury_im.messenger.xmpp_core.RosterHandler;
import java.util.Collection;
@ -29,10 +36,12 @@ public class RoomRosterHandler implements RosterHandler {
private final long accountId;
private final Roster roster;
private final MercuryConnection connection;
public RoomRosterHandler(long accountId, Roster roster) {
this.accountId = accountId;
this.roster = roster;
public RoomRosterHandler(MercuryConnection connection) {
this.connection = connection;
this.accountId = connection.getAccountId();
this.roster = connection.getRoster();
MercuryImApplication.getApplication().getAppComponent().inject(this);
}
@ -78,6 +87,7 @@ public class RoomRosterHandler implements RosterHandler {
}
@Transaction
private RoomContactModel getContactModel(Jid jid) {
Log.d(TAG, "Build entity " + jid + " " + accountId);
EntityBareJid entityBareJid = jid.asEntityBareJidOrThrow();
@ -97,4 +107,29 @@ public class RoomRosterHandler implements RosterHandler {
}
return contactModel;
}
@Override
public void presenceAvailable(FullJid address, Presence availablePresence) {
}
@Override
public void presenceUnavailable(FullJid address, Presence presence) {
}
@Override
public void presenceError(Jid address, Presence errorPresence) {
}
@Override
public void presenceSubscribed(BareJid address, Presence subscribedPresence) {
}
@Override
public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) {
}
}

View File

@ -54,6 +54,7 @@ import org.mercury_im.messenger.persistence.room.repository.IAccountRepository;
import org.mercury_im.messenger.persistence.room.repository.IContactRepository;
import org.mercury_im.messenger.persistence.room.repository.IEntityRepository;
import org.mercury_im.messenger.ui.MainActivity;
import org.mercury_im.messenger.xmpp_android.AndroidMercuryConnection;
import org.mercury_im.messenger.xmpp_android.ParcelableXMPPTCPConnectionConfiguration;
import org.mercury_im.messenger.xmpp_core.ConnectionHolder;
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
@ -226,9 +227,9 @@ public class XmppConnectionService extends Service implements ConnectionHolder {
try {
XMPPTCPConnection connection = new XMPPTCPConnection(accountModel.getJid().getLocalpart().asUnescapedString(),
accountModel.getPassword(), accountModel.getJid().getDomain().toString());
MercuryConnection mercuryConnection = new MercuryConnection(connection, accountModel.getId());
MercuryConnection mercuryConnection = new AndroidMercuryConnection(connection, accountModel.getId());
putConnection(accountModel.getId(), mercuryConnection);
mercuryConnection.setRosterHandler(new RoomRosterHandler(accountModel.getId(), Roster.getInstanceFor(connection)));
mercuryConnection.setRosterHandler(new RoomRosterHandler(mercuryConnection));
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
connection.connect().login();

View File

@ -83,7 +83,7 @@ public class ChatActivity extends BindingActivity implements ChatInputFragment.O
}
});
getSupportFragmentManager().beginTransaction().replace(R.id.fab, ChatInputFragment.newInstance())
getSupportFragmentManager().beginTransaction().replace(R.id.stub_compose, ChatInputFragment.newInstance())
.commitAllowingStateLoss();
}
}

View File

@ -35,6 +35,9 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
@BindView(R.id.btn_send)
ImageButton buttonSend;
@BindView(R.id.btn_emoji)
ImageButton buttonEmoji;
private ChatInputViewModel mViewModel;
private OnChatInputActionListener actionListener;
@ -48,7 +51,7 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.view_chat_field, container, false);
View view = inflater.inflate(R.layout.view_compose, container, false);
ButterKnife.bind(this, view);
return view;
}
@ -113,6 +116,10 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
}
textInput.setText(null);
break;
case R.id.btn_emoji:
Toast.makeText(getContext(), "Not yet implemented!", Toast.LENGTH_SHORT).show();
break;
}
}

View File

@ -37,6 +37,12 @@ public class ChatRecyclerViewAdapter extends RecyclerView.Adapter<ChatRecyclerVi
@Override
public void onBindViewHolder(@NonNull ChatItemViewHolder holder, int position) {
MessageModel message = messages.get(position);
MessageBackgroundDrawable background = getBackgroundDrawable(position);
if (message.isIncoming()) {
holder.body.setBackgroundResource(background.getIn());
} else {
holder.body.setBackgroundResource(background.getOut());
}
holder.body.setText(message.getBody());
}
@ -64,4 +70,47 @@ public class ChatRecyclerViewAdapter extends RecyclerView.Adapter<ChatRecyclerVi
body = itemView.findViewById(R.id.msg_body);
}
}
enum MessageBackgroundDrawable {
FIRST(R.drawable.bg_msg_in_first, R.drawable.bg_msg_out_first),
MID(R.drawable.bg_msg_in_mid, R.drawable.bg_msg_out_mid),
LAST(R.drawable.bg_msg_in_last, R.drawable.bg_msg_out_last),
SINGLE(R.drawable.bg_msg_single, R.drawable.bg_msg_single),
;
private final int in, out;
MessageBackgroundDrawable(int in, int out) {
this.in = in;
this.out = out;
}
public int getIn() {
return in;
}
public int getOut() {
return out;
}
}
public MessageBackgroundDrawable getBackgroundDrawable(int pos) {
MessageModel m = messages.get(pos);
MessageModel b = pos != 0 ? messages.get(pos - 1) : null;
MessageModel a = pos != messages.size() - 1 ? messages.get(pos + 1) : null;
if (b == null || b.isIncoming() != m.isIncoming()) {
if (a == null || a.isIncoming() != m.isIncoming()) {
return MessageBackgroundDrawable.SINGLE;
} else {
return MessageBackgroundDrawable.FIRST;
}
} else {
if (a == null || a.isIncoming() != m.isIncoming()) {
return MessageBackgroundDrawable.LAST;
} else {
return MessageBackgroundDrawable.MID;
}
}
}
}

View File

@ -13,6 +13,7 @@ import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.ui.BindingActivity;
import javax.inject.Inject;
@ -27,7 +28,6 @@ public class AccountsActivity extends FragmentActivity implements AccountsFragme
setContentView(R.layout.content_accounts);
MercuryImApplication.getApplication().getAppComponent().inject(this);
}
@Override

View File

@ -30,6 +30,7 @@ import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.ui.BindingActivity;
import org.mercury_im.messenger.handler.RoomRosterHandler;
import org.mercury_im.messenger.xmpp_android.AndroidMercuryConnection;
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
import java.io.IOException;
@ -152,9 +153,9 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
try {
XMPPTCPConnection connection = new XMPPTCPConnection(accountModel.getJid().getLocalpart().asUnescapedString(),
accountModel.getPassword(), accountModel.getJid().getDomain().toString());
MercuryConnection mercuryConnection = new MercuryConnection(connection, accountModel.getId());
MercuryConnection mercuryConnection = new AndroidMercuryConnection(connection, accountModel.getId());
connectionService.putConnection(accountModel.getId(), mercuryConnection);
mercuryConnection.setRosterHandler(new RoomRosterHandler(accountModel.getId(), Roster.getInstanceFor(connection)));
mercuryConnection.setRosterHandler(new RoomRosterHandler(mercuryConnection));
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
connection.connect().login();

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="18dp" />
<solid android:color="@color/white" />
<stroke android:color="@color/outline_compose" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big" android:bottomLeftRadius="@dimen/msg_corner_small"/>
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big" android:topLeftRadius="@dimen/msg_corner_small"/>
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big"
android:topLeftRadius="@dimen/msg_corner_small"
android:bottomLeftRadius="@dimen/msg_corner_small" />
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big"
android:bottomRightRadius="@dimen/msg_corner_small" />
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big"
android:topRightRadius="@dimen/msg_corner_small" />
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big"
android:topRightRadius="@dimen/msg_corner_small"
android:bottomRightRadius="@dimen/msg_corner_small"/>
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/msg_corner_big" />
<solid android:color="@color/bg_msg_out" />
<stroke android:color="@color/outline_msg" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#FFF" />
<size android:width="10dp" android:height="10dp" />
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="oval"
xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="10dp" android:height="10dp" />
<solid android:color="@color/white" />
<stroke android:color="@color/outline_compose" android:width="@dimen/width_outline" />
</shape>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M16.5,6v11.5c0,2.21 -1.79,4 -4,4s-4,-1.79 -4,-4V5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5v10.5c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V6H10v9.5c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5V5c0,-2.21 -1.79,-4 -4,-4S7,2.79 7,5v12.5c0,3.04 2.46,5.5 5.5,5.5s5.5,-2.46 5.5,-5.5V6h-1.5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,17.5c2.33,0 4.31,-1.46 5.11,-3.5L6.89,14c0.8,2.04 2.78,3.5 5.11,3.5z"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="@dimen/msg_corner_big" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white" />
<stroke android:color="@color/outline_compose" android:width="@dimen/width_outline" />
</shape>

View File

@ -19,7 +19,14 @@ tools:context=".ui.chat.ChatActivity">
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
app:popupTheme="@style/AppTheme.PopupOverlay">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/aldrin"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
@ -34,13 +41,9 @@ tools:context=".ui.chat.ChatActivity">
<FrameLayout
android:id="@+id/fab"
android:id="@+id/stub_compose"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">
<include layout="@layout/view_chat_field"/>
</FrameLayout>
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -11,7 +11,7 @@
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="100dp"
android:paddingBottom="56dp"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

View File

@ -25,12 +25,23 @@
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:singleLine="true"
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="8dp"
android:autoSizeMaxTextSize="18dp"
app:layout_constraintEnd_toStartOf="@+id/switch_account_enabled"
app:layout_constraintStart_toEndOf="@+id/avatar_account"
app:layout_constraintTop_toTopOf="parent"
tools:text="buzz@jabber.nasa.gov" />
tools:text="buzzlightyear@jabber.nasa.gov" />
<TextView
android:id="@+id/text_account_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="@+id/avatar_account"
app:layout_constraintTop_toBottomOf="@+id/text_account_jid"
tools:text="Online" />
<Switch
android:id="@+id/switch_account_enabled"

View File

@ -0,0 +1,78 @@
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/bg_compose"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_send"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="@+id/btn_emoji"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:background="@null"
android:tint="@color/tint_compose"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/ic_insert_emoticon_white_24dp" />
<EditText
android:id="@+id/text_body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@null"
android:hint="Type your message"
android:inputType="textMultiLine|textAutoCorrect"
android:maxLines="6"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_media"
app:layout_constraintStart_toEndOf="@id/btn_emoji"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/btn_media"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@null"
android:tint="@color/tint_compose"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_attach_file_white_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageButton
android:id="@+id/btn_send"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/circle_outlined"
android:tint="@color/tint_compose"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_send_black_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,11 +2,14 @@
<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:layout_marginTop="@dimen/msg_spacing_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/msg_avatar"
android:visibility="gone"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
@ -19,18 +22,17 @@
android:id="@+id/msg_body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginStart="12dp"
android:background="@drawable/bg_msg_bubble_incoming"
android:lineSpacingExtra="2dp"
android:paddingStart="20dp"
android:paddingTop="4dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
android:layout_marginStart="@dimen/msg_margin_horizontal"
android:paddingStart="@dimen/msg_padding_start"
android:paddingTop="@dimen/msg_padding_top"
android:paddingEnd="@dimen/msg_padding_end"
android:paddingBottom="@dimen/msg_padding_bottom"
app:layout_constraintStart_toEndOf="@id/msg_avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_max="wrap"
app:layout_constraintWidth_percent="0.8"
android:background="@drawable/bg_msg_single"
android:lineSpacingExtra="2dp"
tools:text="Hello World! I greet you fellow messengers. Please await my overpowering!" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -11,14 +11,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="2dp"
android:paddingEnd="20dp"
android:paddingTop="4dp"
android:paddingStart="10dp"
android:paddingBottom="10dp"
android:layout_margin="8dp"
android:layout_marginTop="8dp"
android:paddingStart="@dimen/msg_padding_start"
android:paddingTop="@dimen/msg_padding_top"
android:paddingEnd="@dimen/msg_padding_end"
android:paddingBottom="@dimen/msg_padding_bottom"
android:layout_marginTop="2dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_msg_bubble_outgoing"
android:background="@drawable/bg_msg_single"
android:maxWidth="300dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"

View File

@ -1,8 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#FFF</color>
<color name="colorPrimary">#38445e</color>
<color name="colorPrimaryDark">#0f1d34</color>
<color name="colorAccent">#636f8b</color>
<color name="background">#ECEFF1</color>
<color name="background">#EDF0F2</color>
<color name="bg_msg_in">#FFF</color>
<color name="bg_msg_out">#FFF</color>
<color name="outline_msg">#BBB</color>
<color name="outline_compose">#999</color>
<color name="tint_compose">#444</color>
</resources>

View File

@ -4,4 +4,22 @@
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="text_margin">16dp</dimen>
<!-- msg -->
<dimen name="msg_min_height">36dp</dimen>
<dimen name="msg_corner_big">18dp</dimen>
<dimen name="msg_corner_small">4dp</dimen>
<dimen name="msg_margin_horizontal">8dp</dimen>
<dimen name="msg_spacing_vertical">1dp</dimen>
<dimen name="msg_padding_horizontal">10dp</dimen>
<dimen name="msg_padding_vertical">10dp</dimen>
<dimen name="msg_padding_top">@dimen/msg_padding_vertical</dimen>
<dimen name="msg_padding_bottom">@dimen/msg_padding_vertical</dimen>
<dimen name="msg_padding_start">@dimen/msg_padding_horizontal</dimen>
<dimen name="msg_padding_end">@dimen/msg_padding_horizontal</dimen>
<dimen name="width_outline">1dp</dimen>
</resources>

View File

@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Transaction;
import androidx.room.TypeConverters;
import org.jxmpp.jid.EntityBareJid;

View File

@ -0,0 +1,21 @@
package org.mercury_im.messenger.xmpp_android;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import org.mercury_im.messenger.xmpp_core.ConnectionState;
import org.mercury_im.messenger.xmpp_core.ConnectionStateHolder;
public class AndroidConnectionStateHolder implements ConnectionStateHolder {
private MutableLiveData<ConnectionState> connectionState = new MutableLiveData<>();
@Override
public void updateConnectionState(ConnectionState state) {
this.connectionState.postValue(state);
}
public LiveData<ConnectionState> getConnectionState() {
return connectionState;
}
}

View File

@ -0,0 +1,18 @@
package org.mercury_im.messenger.xmpp_android;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.mercury_im.messenger.xmpp_core.ConnectionStateHolder;
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
public class AndroidMercuryConnection extends MercuryConnection {
public AndroidMercuryConnection(XMPPTCPConnection connection, long accountId) {
super(connection, accountId);
this.stateHolder = new AndroidConnectionStateHolder();
}
@Override
public ConnectionStateHolder getState() {
return stateHolder;
}
}

View File

@ -0,0 +1,6 @@
package org.mercury_im.messenger.xmpp_core;
public interface ConnectionStateHolder {
void updateConnectionState(ConnectionState state);
}

View File

@ -8,7 +8,7 @@ import org.jivesoftware.smack.util.ExceptionCallback;
import org.jivesoftware.smackx.carbons.CarbonManager;
import org.whispersystems.libsignal.logging.Log;
public class MercuryConnection implements ConnectionListener {
public abstract class MercuryConnection implements ConnectionListener {
public static final String TAG = "Mercury";
@ -18,6 +18,7 @@ public class MercuryConnection implements ConnectionListener {
protected final Roster roster;
protected final ChatManager chatManager;
protected final CarbonManager carbonManager;
protected ConnectionStateHolder stateHolder;
public MercuryConnection(XMPPConnection connection, long accountId) {
this.connection = connection;
@ -45,6 +46,8 @@ public class MercuryConnection implements ConnectionListener {
chatManager.addOutgoingListener(plainMessageHandler);
}
public abstract ConnectionStateHolder getState();
public long getAccountId() {
return accountId;
}
@ -55,7 +58,7 @@ public class MercuryConnection implements ConnectionListener {
@Override
public void connected(XMPPConnection connection) {
getState().updateConnectionState(ConnectionState.CONNECTED);
}
@Override
@ -64,15 +67,18 @@ public class MercuryConnection implements ConnectionListener {
carbonManager.enableCarbonsAsync(exception ->
Log.e("Mercury", "Could not enable carbons for connection " + accountId + ":", exception));
}
getState().updateConnectionState(ConnectionState.CONNECTED);
}
@Override
public void connectionClosed() {
Log.i(TAG, "Connection closed.");
getState().updateConnectionState(ConnectionState.DISCONNECTED);
}
@Override
public void connectionClosedOnError(Exception e) {
Log.e(TAG, "Connection closed on error.", e);
getState().updateConnectionState(ConnectionState.DISCONNECTED);
}
}

View File

@ -1,8 +1,9 @@
package org.mercury_im.messenger.xmpp_core;
import org.jivesoftware.smack.roster.PresenceEventListener;
import org.jivesoftware.smack.roster.RosterListener;
import org.jivesoftware.smack.roster.RosterLoadedListener;
public interface RosterHandler extends RosterListener, RosterLoadedListener {
public interface RosterHandler extends RosterListener, RosterLoadedListener, PresenceEventListener {
}