Temp
This commit is contained in:
parent
d5153f400e
commit
fafd8b9f6f
|
@ -99,9 +99,12 @@ dependencies {
|
|||
implementation 'androidx.recyclerview:recyclerview:1.0.0'
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
|
||||
// circular image viewer for avatars
|
||||
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
||||
|
||||
// Smack Android
|
||||
implementation "org.igniterealtime.smack:smack-android-extensions:$smackAndroidExtensionsVersion"
|
||||
}
|
||||
|
|
|
@ -24,11 +24,10 @@
|
|||
android:theme="@style/AppTheme.NoActionBar"/>
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:label="@string/title_activity_main"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.util.Log;
|
|||
import android.util.LongSparseArray;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
@ -31,6 +32,7 @@ import org.jivesoftware.smack.roster.RosterEntry;
|
|||
import org.jivesoftware.smack.roster.RosterLoadedListener;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||
import org.jivesoftware.smackx.ping.android.ServerPingWithAlarmManager;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.Notifications;
|
||||
|
@ -96,11 +98,10 @@ public class XmppConnectionService extends Service {
|
|||
|
||||
private Handler uiHandler;
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
@Override
|
||||
public final IBinder onBind(Intent intent) {
|
||||
// We are a started service, so we don't provide a binding and always return null.
|
||||
return null;
|
||||
return new Binder(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,6 +109,20 @@ public class XmppConnectionService extends Service {
|
|||
super.onCreate();
|
||||
Log.d(TAG, "onCreate()");
|
||||
MercuryImApplication.getApplication().getAppComponent().inject(this);
|
||||
|
||||
// Begin life cycle of Ping Manager.
|
||||
// The Manager will automatically detect newly created connections and ping the server
|
||||
// every half hour if necessary.
|
||||
ServerPingWithAlarmManager.onCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.d(TAG, "onDestroy()");
|
||||
|
||||
// End life cycle of Ping Manager.
|
||||
ServerPingWithAlarmManager.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -240,9 +255,10 @@ public class XmppConnectionService extends Service {
|
|||
Set<RosterEntry> entries = roster.getEntries();
|
||||
for (RosterEntry e : entries) {
|
||||
Log.d(TAG, "Inserting Roster entry " + e.getJid().toString());
|
||||
RoomContactModel m = new RoomContactModel(e.getJid().asEntityBareJidIfPossible(), e.getName(), e.getName());
|
||||
m.setAccountId(accountId);
|
||||
rosterRepository.updateOrInsertRosterEntry(m);
|
||||
|
||||
RoomContactModel contact = new RoomContactModel();
|
||||
contact.setAccountId(accountId);
|
||||
// TODO: Fix
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,4 +297,17 @@ public class XmppConnectionService extends Service {
|
|||
public void putConnection(int accountId, XMPPConnection connection) {
|
||||
connections.put(accountId, connection);
|
||||
}
|
||||
|
||||
public class Binder extends android.os.Binder {
|
||||
|
||||
private final XmppConnectionService service;
|
||||
|
||||
public Binder(XmppConnectionService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public XmppConnectionService getService() {
|
||||
return service;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package org.mercury_im.messenger.service;
|
||||
|
||||
import android.os.Binder;
|
||||
|
||||
public class XmppConnectionServiceBinder extends Binder {
|
||||
|
||||
}
|
|
@ -43,7 +43,7 @@ public class RosterRecyclerViewAdapter
|
|||
// switch (holder.getItemViewType()) {
|
||||
// case RosterItemViewHolder.TYPE:
|
||||
RosterItemViewHolder rosterItem = (RosterItemViewHolder) holder;
|
||||
rosterItem.jidView.setText(model.getJid().toString());
|
||||
//rosterItem.jidView.setText(model.getJid().toString());
|
||||
rosterItem.nicknameView.setText(model.getNickname());
|
||||
rosterItem.itemView.setTag(model);
|
||||
// break;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<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_width="match_parent"
|
||||
|
@ -12,25 +11,23 @@
|
|||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="@drawable/aldrin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/msg_bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:minHeight="48dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/msg_avatar"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
card_view:cardCornerRadius="24dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/msg_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
|
@ -39,5 +36,4 @@
|
|||
</androidx.cardview.widget.CardView>
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,11 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<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_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/msg_bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
|
@ -16,6 +19,7 @@
|
|||
card_view:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/msg_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="300dp"
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<resources>
|
||||
<string name="app_name">Mercury</string>
|
||||
|
||||
<!-- Main Activity -->
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
|
||||
<!-- Login -->
|
||||
<string name="title_activity_login">Log in</string>
|
||||
<!-- Strings related to login -->
|
||||
<string name="prompt_jid">XMPP Address</string>
|
||||
<string name="prompt_password">Password</string>
|
||||
<string name="action_sign_in">Sign in</string>
|
||||
|
@ -10,11 +14,21 @@
|
|||
<string name="error_invalid_password">This password is too short</string>
|
||||
<string name="error_incorrect_password">This password is incorrect</string>
|
||||
<string name="error_field_required">This field is required</string>
|
||||
<string name="password_show_password">Show Password</string>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="title_activity_settings">Settings</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
|
||||
<!-- General -->
|
||||
<string name="not_yet_implemented">Not yet implemented!</string>
|
||||
|
||||
<!-- Strings related to Settings -->
|
||||
<!-- Notifications -->
|
||||
<string name="channel_name_foreground">Foreground Service</string>
|
||||
<string name="channel_description_foreground">Service that keeps the app running</string>
|
||||
|
||||
|
||||
<!-- TODO: DELETE BELOW STUFF -->
|
||||
<!-- Example General settings -->
|
||||
<string name="pref_header_general">General</string>
|
||||
|
||||
|
@ -84,9 +98,5 @@
|
|||
<string name="pref_ringtone_silent">Silent</string>
|
||||
|
||||
<string name="pref_title_vibrate">Vibrate</string>
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="channel_name_foreground">Foreground Service</string>
|
||||
<string name="channel_description_foreground">Service that keeps the app running</string>
|
||||
<string name="password_show_password">Show Password</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.4.0'
|
||||
classpath 'com.android.tools.build:gradle:3.4.1'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Room Persistence Layer of Mercury
|
||||
|
||||
This Android Module contains an implementation of the interfaces of the `persistence` module.
|
||||
In particular it defines SQL schemes and provides DAOs as well as implementations of Model classes
|
||||
and Repositories that utilize the [Room Database Framework](https://developer.android.com/topic/libraries/architecture/room).
|
||||
|
||||
## Packages and Classes
|
||||
|
||||
### `AppDatabase`
|
||||
defines what makes up the database itself. It lists all available entities and provides dao classes.
|
||||
|
||||
### `dao` package
|
||||
Contains data access objects (DAOs) which provide CRUD methods (Create, Read, Update, Delete) for
|
||||
all the models.
|
||||
|
||||
Note, that the `BaseDao` interface already defines methods for creating, updating and deleting
|
||||
entities and is extended by most DAO classes.
|
||||
|
||||
### `model` package
|
||||
Contains classes that represent the data itself in form of models.
|
||||
|
||||
### `repository` package
|
||||
Contains implementations of data repositories. Repositories are single sources of truth and provide
|
||||
a user-friendly separation layer between the application and the DAOs.
|
||||
|
||||
Ideally this layer would also provide access to the XMPP domain, but this is still subject to
|
||||
discussion.
|
||||
|
||||
### `type_converter` package
|
||||
Contains Room specific type converter that convert non-basic data types into basic data types which
|
||||
can be handled by the database and vice versa.
|
|
@ -2,12 +2,18 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "8cbb04481870b8e1320677566696f9ad",
|
||||
"identityHash": "fb56e6a5615c4d1baa6c08d919560267",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "RoomContactModel",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` INTEGER NOT NULL, `jid` TEXT NOT NULL, `rosterName` TEXT, `nickname` TEXT, `avatarFile` TEXT, PRIMARY KEY(`accountId`, `jid`), FOREIGN KEY(`accountId`) REFERENCES `accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`accountId`, `jid`) REFERENCES `entities`(`accountId`, `jid`) ON UPDATE NO ACTION ON DELETE RESTRICT )",
|
||||
"tableName": "contacts",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `accountId` INTEGER NOT NULL, `xmppId` INTEGER NOT NULL, `rosterName` TEXT, `nickname` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`accountId`) REFERENCES `accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`xmppId`) REFERENCES `entities`(`id`) ON UPDATE NO ACTION ON DELETE RESTRICT )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "accountId",
|
||||
"columnName": "accountId",
|
||||
|
@ -15,9 +21,9 @@
|
|||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "jid",
|
||||
"columnName": "jid",
|
||||
"affinity": "TEXT",
|
||||
"fieldPath": "xmppIdentityId",
|
||||
"columnName": "xmppId",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
|
@ -31,30 +37,38 @@
|
|||
"columnName": "nickname",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "avatarFile",
|
||||
"columnName": "avatarFile",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"accountId",
|
||||
"jid"
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_RoomContactModel_accountId_jid",
|
||||
"unique": true,
|
||||
"name": "index_contacts_id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"accountId",
|
||||
"jid"
|
||||
"id"
|
||||
],
|
||||
"createSql": "CREATE UNIQUE INDEX `index_RoomContactModel_accountId_jid` ON `${TABLE_NAME}` (`accountId`, `jid`)"
|
||||
"createSql": "CREATE INDEX `index_contacts_id` ON `${TABLE_NAME}` (`id`)"
|
||||
},
|
||||
{
|
||||
"name": "index_contacts_accountId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"accountId"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_contacts_accountId` ON `${TABLE_NAME}` (`accountId`)"
|
||||
},
|
||||
{
|
||||
"name": "index_contacts_xmppId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"xmppId"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_contacts_xmppId` ON `${TABLE_NAME}` (`xmppId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
|
@ -74,12 +88,10 @@
|
|||
"onDelete": "RESTRICT",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"accountId",
|
||||
"jid"
|
||||
"xmppId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"accountId",
|
||||
"jid"
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -186,6 +198,14 @@
|
|||
"id"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_messages_id` ON `${TABLE_NAME}` (`id`)"
|
||||
},
|
||||
{
|
||||
"name": "index_messages_accountId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"accountId"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_messages_accountId` ON `${TABLE_NAME}` (`accountId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
|
@ -204,8 +224,14 @@
|
|||
},
|
||||
{
|
||||
"tableName": "entities",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` INTEGER NOT NULL, `jid` TEXT NOT NULL, `avatarFile` TEXT, PRIMARY KEY(`accountId`, `jid`), FOREIGN KEY(`accountId`) REFERENCES `accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `accountId` INTEGER NOT NULL, `jid` TEXT NOT NULL, `avatar` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`accountId`) REFERENCES `accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "accountId",
|
||||
"columnName": "accountId",
|
||||
|
@ -220,19 +246,26 @@
|
|||
},
|
||||
{
|
||||
"fieldPath": "avatarFile",
|
||||
"columnName": "avatarFile",
|
||||
"columnName": "avatar",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"accountId",
|
||||
"jid"
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_entities_id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_entities_id` ON `${TABLE_NAME}` (`id`)"
|
||||
},
|
||||
{
|
||||
"name": "index_entities_accountId_jid",
|
||||
"unique": true,
|
||||
|
@ -261,7 +294,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"8cbb04481870b8e1320677566696f9ad\")"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'fb56e6a5615c4d1baa6c08d919560267')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -10,8 +10,14 @@ public interface BaseDao<T> {
|
|||
long insert(T entity);
|
||||
|
||||
@Update
|
||||
void upddate(T... entity);
|
||||
void update(T entity);
|
||||
|
||||
@Update
|
||||
void update(T[] entities);
|
||||
|
||||
@Delete
|
||||
void delete(T... entity);
|
||||
void delete(T entity);
|
||||
|
||||
@Delete
|
||||
void delete(T[] entities);
|
||||
}
|
||||
|
|
|
@ -4,17 +4,25 @@ import androidx.lifecycle.LiveData;
|
|||
import androidx.room.Query;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.model.XmppIdentityModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomChatModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ChatDao extends BaseDao<RoomChatModel> {
|
||||
|
||||
@Query("SELECT * FROM RoomChatModel")
|
||||
@Query("SELECT * FROM chats")
|
||||
LiveData<List<RoomChatModel>> getAllChats();
|
||||
|
||||
@Query("SELECT * FROM RoomChatModel WHERE ")
|
||||
LiveData<RoomChatModel> getChatWith(EntityBareJid contact);
|
||||
@Query("SELECT chats.* FROM chats JOIN entities WHERE accountId = :accountId")
|
||||
LiveData<List<RoomChatModel>> getAllChatsOf(long accountId);
|
||||
|
||||
@Query("SELECT * FROM chats WHERE xmppId = :identityId")
|
||||
LiveData<RoomChatModel> getChatWithIdentity(long identityId);
|
||||
|
||||
@Query("SELECT chats.* FROM chats JOIN entities WHERE accountId = :accountId AND jid = :jid")
|
||||
LiveData<RoomChatModel> getChatWithJid(long accountId, EntityBareJid jid);
|
||||
|
||||
@Query("SELECT * FROM chats JOIN contacts WHERE contacts.id = :contactId")
|
||||
LiveData<RoomChatModel> getChatWithContact(long contactId);
|
||||
}
|
||||
|
|
|
@ -18,14 +18,15 @@ public interface ContactDao extends BaseDao<RoomContactModel> {
|
|||
/**
|
||||
* Return a {@link LiveData} wrapping a {@link List} of all {@link RoomContactModel RosterEntries}
|
||||
* which are currently found in the database.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Query("select * from RoomContactModel")
|
||||
@Query("SELECT * FROM contacts")
|
||||
LiveData<List<RoomContactModel>> getAllRosterEntries();
|
||||
|
||||
@Query("select * from RoomContactModel where jid = :jid")
|
||||
@Query("SELECT contacts.* FROM contacts JOIN entities WHERE jid = :jid")
|
||||
RoomContactModel getRosterEntryByJid(EntityBareJid jid);
|
||||
|
||||
@Query("select * from RoomContactModel where accountId = :accountId")
|
||||
@Query("SELECT * FROM contacts WHERE accountId = :accountId")
|
||||
LiveData<List<RoomContactModel>> getRosterEntriesForAccount(long accountId);
|
||||
}
|
||||
|
|
|
@ -1,67 +1,61 @@
|
|||
package org.mercury_im.messenger.persistence.room.model;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.ForeignKey;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.TypeConverters;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.model.ContactModel;
|
||||
import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
|
||||
import org.mercury_im.messenger.persistence.room.type_converter.FileConverter;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static androidx.room.ForeignKey.CASCADE;
|
||||
import static androidx.room.ForeignKey.RESTRICT;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomContactModel.KEY_ACCOUNT_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomContactModel.KEY_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomContactModel.KEY_XMPP_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomContactModel.TABLE;
|
||||
|
||||
@Entity(primaryKeys = {"accountId", "jid"},
|
||||
indices = {@Index(value = {"accountId", "jid"}, unique = true)},
|
||||
@Entity(tableName = TABLE,
|
||||
indices = {
|
||||
@Index(value = KEY_ID),
|
||||
@Index(value = KEY_ACCOUNT_ID),
|
||||
@Index(value = KEY_XMPP_ID)
|
||||
},
|
||||
foreignKeys = {
|
||||
@ForeignKey(entity = RoomAccountModel.class,
|
||||
parentColumns = "id",
|
||||
childColumns = "accountId",
|
||||
parentColumns = RoomAccountModel.KEY_ID,
|
||||
childColumns = KEY_ACCOUNT_ID,
|
||||
onDelete = CASCADE),
|
||||
@ForeignKey(entity = RoomXmppIdentityModel.class,
|
||||
parentColumns = {"accountId", "jid"},
|
||||
childColumns = {"accountId", "jid"},
|
||||
parentColumns = RoomXmppIdentityModel.KEY_ID,
|
||||
childColumns = KEY_XMPP_ID,
|
||||
onDelete = RESTRICT)})
|
||||
public class RoomContactModel implements ContactModel {
|
||||
|
||||
public static final String TABLE = "contacts";
|
||||
public static final String KEY_ID = "id";
|
||||
public static final String KEY_ACCOUNT_ID = "accountId";
|
||||
public static final String KEY_XMPP_ID = "xmppId";
|
||||
public static final String KEY_ROSTER_NAME = "rosterName";
|
||||
public static final String KEY_NICKNAME = "nickname";
|
||||
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = KEY_ID)
|
||||
private long id;
|
||||
|
||||
@ColumnInfo(name = KEY_ACCOUNT_ID)
|
||||
private long accountId;
|
||||
|
||||
@NonNull
|
||||
@TypeConverters(EntityBareJidConverter.class)
|
||||
private EntityBareJid jid;
|
||||
@ColumnInfo(name = KEY_XMPP_ID)
|
||||
private long xmppIdentityId;
|
||||
|
||||
@ColumnInfo(name = KEY_ROSTER_NAME)
|
||||
private String rosterName;
|
||||
|
||||
@ColumnInfo(name = KEY_NICKNAME)
|
||||
private String nickname;
|
||||
|
||||
@TypeConverters(FileConverter.class)
|
||||
private File avatarFile;
|
||||
|
||||
public RoomContactModel(@NonNull EntityBareJid jid,
|
||||
String rosterName,
|
||||
String nickname) {
|
||||
this.jid = jid;
|
||||
this.nickname = nickname;
|
||||
this.rosterName = rosterName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public EntityBareJid getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJid(EntityBareJid jid) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRosterName() {
|
||||
return rosterName;
|
||||
|
@ -82,6 +76,16 @@ public class RoomContactModel implements ContactModel {
|
|||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
|
@ -92,13 +96,13 @@ public class RoomContactModel implements ContactModel {
|
|||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public File getAvatarFile() {
|
||||
return avatarFile;
|
||||
@Override
|
||||
public long getXmppIdentityId() {
|
||||
return xmppIdentityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAvatarFile(File file) {
|
||||
this.avatarFile = file;
|
||||
public void setXmppIdentityId(long id) {
|
||||
this.xmppIdentityId = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.mercury_im.messenger.persistence.room.model;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.ForeignKey;
|
||||
import androidx.room.Index;
|
||||
|
@ -14,26 +15,50 @@ import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidCon
|
|||
import java.util.Date;
|
||||
|
||||
import static androidx.room.ForeignKey.CASCADE;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomMessageModel.KEY_ACCOUNT_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomMessageModel.KEY_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomMessageModel.TABLE;
|
||||
|
||||
@Entity(tableName = "messages", foreignKeys = @ForeignKey(entity = RoomAccountModel.class,
|
||||
parentColumns = "id", childColumns = "accountId", onDelete = CASCADE),
|
||||
indices = {@Index("id")})
|
||||
@Entity(tableName = TABLE,
|
||||
foreignKeys = {
|
||||
@ForeignKey(entity = RoomAccountModel.class,
|
||||
parentColumns = RoomAccountModel.KEY_ID,
|
||||
childColumns = KEY_ACCOUNT_ID,
|
||||
onDelete = CASCADE)},
|
||||
indices = {
|
||||
@Index(KEY_ID),
|
||||
@Index(KEY_ACCOUNT_ID)
|
||||
})
|
||||
public class RoomMessageModel implements MessageModel {
|
||||
|
||||
public static final String TABLE = "messages";
|
||||
public static final String KEY_ID = "id";
|
||||
public static final String KEY_ACCOUNT_ID = "accountId";
|
||||
public static final String KEY_BODY = "body";
|
||||
public static final String KEY_SEND_DATE = "sendDate";
|
||||
public static final String KEY_FROM = "from";
|
||||
public static final String KEY_TO = "to";
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = KEY_ID)
|
||||
private long id;
|
||||
|
||||
@ColumnInfo(name = KEY_ACCOUNT_ID)
|
||||
private long accountId;
|
||||
|
||||
@ColumnInfo(name = KEY_BODY)
|
||||
private String body;
|
||||
|
||||
@TypeConverters(DateConverter.class)
|
||||
@ColumnInfo(name = KEY_SEND_DATE)
|
||||
private Date sendDate;
|
||||
|
||||
@TypeConverters(EntityBareJidConverter.class)
|
||||
@ColumnInfo(name = KEY_FROM)
|
||||
private EntityBareJid from;
|
||||
|
||||
@TypeConverters(EntityBareJidConverter.class)
|
||||
@ColumnInfo(name = KEY_TO)
|
||||
private EntityBareJid to;
|
||||
|
||||
public RoomMessageModel() {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package org.mercury_im.messenger.persistence.room.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.ForeignKey;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
import androidx.room.TypeConverters;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
|
@ -14,38 +16,54 @@ import org.mercury_im.messenger.persistence.room.type_converter.FileConverter;
|
|||
import java.io.File;
|
||||
|
||||
import static androidx.room.ForeignKey.CASCADE;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomXmppIdentityModel.KEY_ACCOUNT_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomXmppIdentityModel.KEY_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomXmppIdentityModel.KEY_JID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomXmppIdentityModel.TABLE;
|
||||
|
||||
@Entity(tableName = TABLE, primaryKeys = {"accountId", "jid"},
|
||||
indices = {@Index(value = {"accountId", "jid"}, unique = true)},
|
||||
foreignKeys = @ForeignKey(entity = RoomAccountModel.class,
|
||||
parentColumns = "id",
|
||||
childColumns = "accountId",
|
||||
onDelete = CASCADE))
|
||||
@Entity(tableName = TABLE,
|
||||
indices = {
|
||||
@Index(value = KEY_ID),
|
||||
@Index(value = {KEY_ACCOUNT_ID, KEY_JID}, unique = true)
|
||||
},
|
||||
foreignKeys = {
|
||||
@ForeignKey(entity = RoomAccountModel.class,
|
||||
parentColumns = RoomAccountModel.KEY_ID,
|
||||
childColumns = KEY_ACCOUNT_ID,
|
||||
onDelete = CASCADE)
|
||||
})
|
||||
public class RoomXmppIdentityModel implements XmppIdentityModel {
|
||||
|
||||
public static final String TABLE = "entities";
|
||||
public static final String KEY_ID = "id";
|
||||
public static final String KEY_ACCOUNT_ID = "accountId";
|
||||
public static final String KEY_JID = "jid";
|
||||
public static final String KEY_AVATAR = "avatar";
|
||||
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = KEY_ID)
|
||||
protected long id;
|
||||
|
||||
@ColumnInfo(name = KEY_ACCOUNT_ID)
|
||||
protected long accountId;
|
||||
|
||||
@NonNull
|
||||
@TypeConverters(EntityBareJidConverter.class)
|
||||
@ColumnInfo(name = KEY_JID)
|
||||
protected EntityBareJid jid;
|
||||
|
||||
@TypeConverters(FileConverter.class)
|
||||
@ColumnInfo(name = KEY_AVATAR)
|
||||
protected File avatarFile;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return 0;
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(long id) {
|
||||
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -55,7 +73,7 @@ public class RoomXmppIdentityModel implements XmppIdentityModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setJid(EntityBareJid jid) {
|
||||
public void setJid(@NonNull EntityBareJid jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,57 @@
|
|||
package org.mercury_im.messenger.persistence.room.repository;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.room.Index;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.model.AccountModel;
|
||||
import org.mercury_im.messenger.persistence.model.ChatModel;
|
||||
import org.mercury_im.messenger.persistence.model.ContactModel;
|
||||
import org.mercury_im.messenger.persistence.model.XmppIdentityModel;
|
||||
import org.mercury_im.messenger.persistence.repository.ChatRepository;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ChatDao;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomChatModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class IChatRepository implements ChatRepository {
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Override
|
||||
public LiveData<List<ChatModel>> getAllChats() {
|
||||
return null;
|
||||
public class IChatRepository implements ChatRepository<RoomChatModel> {
|
||||
|
||||
private final ChatDao chatDao;
|
||||
|
||||
@Inject
|
||||
public IChatRepository(ChatDao dao) {
|
||||
this.chatDao = dao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getChatWith(XmppIdentityModel identity) {
|
||||
|
||||
public LiveData<List<RoomChatModel>> getAllChats() {
|
||||
return chatDao.getAllChats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChat(ChatModel chat) {
|
||||
public LiveData<List<RoomChatModel>> getAllChatsOf(AccountModel accountModel) {
|
||||
return chatDao.getAllChatsOf(accountModel.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomChatModel> getChatWith(XmppIdentityModel identity) {
|
||||
return chatDao.getChatWithIdentity(identity.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomChatModel> getChatWith(AccountModel account, EntityBareJid jid) {
|
||||
return chatDao.getChatWithJid(account.getId(), jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomChatModel> getChatWith(ContactModel contact) {
|
||||
return chatDao.getChatWithContact(contact.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChat(RoomChatModel chat) {
|
||||
chatDao.delete(chat);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# Abstract Persistence Layer of Mercury
|
||||
|
||||
This Android module defines interfaces for a persistence backend.
|
||||
|
||||
Ideally this module would at some point be a plain java (non-Android) module to allow for
|
||||
non-Android implementations. This is currently being blocked by [LiveData](https://developer.android.com/topic/libraries/architecture/livedata)
|
||||
being an Android library. We could fix this by replacing LiveData with RxJava, but this would
|
||||
require us to manually handle LifeCycles of ViewModels etc. so for now we stick with LiveData.
|
||||
|
||||
## Packages
|
||||
|
||||
### `model` package
|
||||
Contains interfaces that define the structure of data classes.
|
||||
|
||||
### `repository` package
|
||||
Repositories build a user-friendly interface to query and modify data in the backend.
|
||||
|
||||
## Implementations
|
||||
Currently the module is only being implemented by the `persistence-room` Android module.
|
|
@ -1,7 +1,5 @@
|
|||
package org.mercury_im.messenger.persistence.model;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
|
||||
public interface ChatModel {
|
||||
|
||||
long getId();
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package org.mercury_im.messenger.persistence.model;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface ContactModel {
|
||||
|
||||
long getId();
|
||||
|
@ -14,9 +10,9 @@ public interface ContactModel {
|
|||
|
||||
void setAccountId(long id);
|
||||
|
||||
EntityBareJid getJid();
|
||||
long getXmppIdentityId();
|
||||
|
||||
void setJid(EntityBareJid jid);
|
||||
void setXmppIdentityId(long id);
|
||||
|
||||
String getRosterName();
|
||||
|
||||
|
@ -25,8 +21,4 @@ public interface ContactModel {
|
|||
String getNickname();
|
||||
|
||||
void setNickname(String nickname);
|
||||
|
||||
File getAvatarFile();
|
||||
|
||||
void setAvatarFile(File file);
|
||||
}
|
||||
|
|
|
@ -2,17 +2,26 @@ package org.mercury_im.messenger.persistence.repository;
|
|||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.model.AccountModel;
|
||||
import org.mercury_im.messenger.persistence.model.ChatModel;
|
||||
import org.mercury_im.messenger.persistence.model.ContactModel;
|
||||
import org.mercury_im.messenger.persistence.model.XmppIdentityModel;
|
||||
import org.w3c.dom.Entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ChatRepository {
|
||||
public interface ChatRepository<E extends ChatModel> {
|
||||
|
||||
LiveData<List<ChatModel>> getAllChats();
|
||||
LiveData<List<E>> getAllChats();
|
||||
|
||||
LiveData<ChatModel> getChatWith(XmppIdentityModel identity);
|
||||
LiveData<List<E>> getAllChatsOf(AccountModel account);
|
||||
|
||||
void closeChat(ChatModel chat);
|
||||
LiveData<E> getChatWith(AccountModel account, EntityBareJid jid);
|
||||
|
||||
LiveData<E> getChatWith(XmppIdentityModel identity);
|
||||
|
||||
LiveData<E> getChatWith(ContactModel contact);
|
||||
|
||||
void closeChat(E chat);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ ext {
|
|||
|
||||
/*/
|
||||
// Version strings for unique versions
|
||||
// https://github.com/igniterealtime/Smack/wiki/How-to-use-Smack-snapshots
|
||||
|
||||
smackAndroidVersion = "4.4.0-alpha2-20190324.010646-51"
|
||||
smackAndroidExtensionsVersion = "4.4.0-alpha2-20190324.010646-51"
|
||||
smackCoreVersion = "4.4.0-alpha2-20190324.010647-51"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.mercury_im.messenger.xmpp_android;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smackx.ping.android.ServerPingWithAlarmManager;
|
||||
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
|
||||
|
||||
public class AndroidMercuryConnection extends MercuryConnection {
|
||||
|
|
|
@ -11,8 +11,8 @@ dependencies {
|
|||
api "org.igniterealtime.smack:smack-omemo:$smackOmemoVersion"
|
||||
api "org.igniterealtime.smack:smack-omemo-signal:$smackOmemoSignalVersion"
|
||||
api "org.igniterealtime.smack:smack-openpgp:$smackOpenPGPVersion"
|
||||
api "org.igniterealtime.smack:smack-resolver-minidns:$smackResolverMiniDnsVersion"
|
||||
api "org.igniterealtime.smack:smack-tcp:$smackTcpVersion"
|
||||
// api "org.igniterealtime.smack:smack-resolver-minidns:$smackResolverMiniDnsVersion"
|
||||
// api "org.igniterealtime.smack:smack-tcp:$smackTcpVersion"
|
||||
|
||||
// Exclude XmlPullParser from Smack dependencies, as its now provided by Android
|
||||
// https://stackoverflow.com/questions/48488563/gradle-xpp3-error/48746294#48746294
|
||||
|
|
|
@ -5,9 +5,9 @@ import org.jivesoftware.smack.roster.Roster;
|
|||
|
||||
public class MercuryConnection {
|
||||
|
||||
private final XMPPConnection connection;
|
||||
private final long accountId;
|
||||
private final Roster roster;
|
||||
protected final XMPPConnection connection;
|
||||
protected final long accountId;
|
||||
protected final Roster roster;
|
||||
|
||||
public MercuryConnection(XMPPConnection connection, long accountId) {
|
||||
this.connection = connection;
|
||||
|
|
Loading…
Reference in New Issue