From 3159a4dce0251446a19edc871582951e0ff7cb33 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Thu, 3 Oct 2024 19:29:04 +0530 Subject: [PATCH 1/3] Added tables Added tables and DB upgradation --- .../models/ConnectMessagingChannelRecord.java | 130 +++++++++++++++++ .../models/ConnectMessagingMessageRecord.java | 131 ++++++++++++++++++ .../org/commcare/connect/MessageManager.java | 14 ++ .../connect/ConnectDatabaseUpgrader.java | 12 ++ .../connect/DatabaseConnectOpenHelper.java | 10 +- 5 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 app/src/org/commcare/android/database/connect/models/ConnectMessagingChannelRecord.java create mode 100644 app/src/org/commcare/android/database/connect/models/ConnectMessagingMessageRecord.java create mode 100644 app/src/org/commcare/connect/MessageManager.java diff --git a/app/src/org/commcare/android/database/connect/models/ConnectMessagingChannelRecord.java b/app/src/org/commcare/android/database/connect/models/ConnectMessagingChannelRecord.java new file mode 100644 index 000000000..e6cf5f42f --- /dev/null +++ b/app/src/org/commcare/android/database/connect/models/ConnectMessagingChannelRecord.java @@ -0,0 +1,130 @@ +package org.commcare.android.database.connect.models; + +import org.commcare.android.storage.framework.Persisted; +import org.commcare.models.framework.Persisting; +import org.commcare.modern.database.Table; +import org.commcare.modern.models.MetaField; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.Serializable; +import java.text.ParseException; + +@Table(ConnectMessagingChannelRecord.STORAGE_KEY) +public class ConnectMessagingChannelRecord extends Persisted implements Serializable { + + /** + * Name of database that stores Connect payment units + */ + public static final String STORAGE_KEY = "connect_messaging_channel"; + + public static final String META_CHANNEL_ID = "channel_id "; + public static final String META_CHANNEL_CREATED = "created"; + public static final String META_ANSWERED_CONSENT = "answered_consent"; + public static final String META_CONSENTED = "consented"; + public static final String META_CHANNEL_NAME = "name"; + public static final String META_KEY_URL = "key_url"; + public static final String META_KEY = "key"; + + public ConnectMessagingChannelRecord() { + + } + + @Persisting(1) + @MetaField(META_CHANNEL_ID) + private int channelId; + + @Persisting(2) + @MetaField(META_CHANNEL_CREATED) + private String channelCreated; + + @Persisting(3) + @MetaField(META_ANSWERED_CONSENT) + private String answeredConsent; + + @Persisting(4) + @MetaField(META_CONSENTED) + private String consented; + + @Persisting(5) + @MetaField(META_CHANNEL_NAME) + private String channelName; + + @Persisting(6) + @MetaField(META_KEY_URL) + private String keyUrl; + + @Persisting(7) + @MetaField(META_KEY) + private String key; + + public static ConnectMessagingChannelRecord fromJson(JSONObject json) throws JSONException, ParseException { + ConnectMessagingChannelRecord connectMessagingChannelRecord = new ConnectMessagingChannelRecord(); + + connectMessagingChannelRecord.channelId = json.getInt(META_CHANNEL_ID); + connectMessagingChannelRecord.channelCreated = json.getString(META_CHANNEL_CREATED); + connectMessagingChannelRecord.answeredConsent = json.getString(META_ANSWERED_CONSENT); + connectMessagingChannelRecord.consented = json.getString(META_CONSENTED); + connectMessagingChannelRecord.channelName = json.getString(META_CHANNEL_NAME); + connectMessagingChannelRecord.keyUrl = json.getString(META_KEY_URL); + connectMessagingChannelRecord.key = json.getString(META_KEY); + + return connectMessagingChannelRecord; + } + + public int getChannelId() { + return channelId; + } + + public void setChannelId(int channelId) { + this.channelId = channelId; + } + + public String getChannelCreated() { + return channelCreated; + } + + public void setChannelCreated(String channelCreated) { + this.channelCreated = channelCreated; + } + + public String getAnsweredConsent() { + return answeredConsent; + } + + public void setAnsweredConsent(String answeredConsent) { + this.answeredConsent = answeredConsent; + } + + public String getConsented() { + return consented; + } + + public void setConsented(String consented) { + this.consented = consented; + } + + public String getChannelName() { + return channelName; + } + + public void setChannelName(String channelName) { + this.channelName = channelName; + } + + public String getKeyUrl() { + return keyUrl; + } + + public void setKeyUrl(String keyUrl) { + this.keyUrl = keyUrl; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } +} diff --git a/app/src/org/commcare/android/database/connect/models/ConnectMessagingMessageRecord.java b/app/src/org/commcare/android/database/connect/models/ConnectMessagingMessageRecord.java new file mode 100644 index 000000000..8e3910682 --- /dev/null +++ b/app/src/org/commcare/android/database/connect/models/ConnectMessagingMessageRecord.java @@ -0,0 +1,131 @@ +package org.commcare.android.database.connect.models; + +import org.commcare.android.storage.framework.Persisted; +import org.commcare.models.framework.Persisting; +import org.commcare.modern.database.Table; +import org.commcare.modern.models.MetaField; +import org.json.JSONException; +import org.json.JSONObject; +import org.simpleframework.xml.core.PersistenceException; + +import java.io.Serializable; +import java.text.ParseException; + +@Table(ConnectMessagingMessageRecord.STORAGE_KEY) +public class ConnectMessagingMessageRecord extends Persisted implements Serializable { + + /** + * Name of database that stores Connect payment units + */ + public static final String STORAGE_KEY = "connect_messaging_message"; + + public static final String META_MESSAGE_ID = "message_id"; + public static final String META_MESSAGE_CHANNEL_ID = "channel_id"; + public static final String META_MESSAGE_TIMESTAMP = "timestamp"; + public static final String META_MESSAGE = "message"; + public static final String META_MESSAGE_IS_OUTGOING = "is_outgoing"; + public static final String META_MESSAGE_CONFIRM = "confirmed"; + public static final String META_MESSAGE_USER_VIEWED = "user_viewed"; + + public ConnectMessagingMessageRecord() { + + } + + @Persisting(1) + @MetaField(META_MESSAGE_ID) + private int messageId; + + @Persisting(2) + @MetaField(META_MESSAGE_CHANNEL_ID) + private int channelId; + + @Persisting(3) + @MetaField(META_MESSAGE_TIMESTAMP) + private String timeStamp; + + @Persisting(4) + @MetaField(META_MESSAGE) + private String message; + + @Persisting(5) + @MetaField(META_MESSAGE_IS_OUTGOING) + private String isOutgoing; + + @Persisting(6) + @MetaField(META_MESSAGE_CONFIRM) + private String confirmed; + + @Persisting(7) + @MetaField(META_MESSAGE_USER_VIEWED) + private String userViewed; + + private static ConnectMessagingMessageRecord fromJson(JSONObject json) throws JSONException, ParseException{ + ConnectMessagingMessageRecord connectMessagingMessageRecord = new ConnectMessagingMessageRecord(); + + connectMessagingMessageRecord.messageId = json.getInt(META_MESSAGE_ID); + connectMessagingMessageRecord.channelId = json.getInt(META_MESSAGE_CHANNEL_ID); + connectMessagingMessageRecord.timeStamp = json.getString(META_MESSAGE_TIMESTAMP); + connectMessagingMessageRecord.message = json.getString(META_MESSAGE); + connectMessagingMessageRecord.isOutgoing = json.getString(META_MESSAGE_IS_OUTGOING); + connectMessagingMessageRecord.confirmed = json.getString(META_MESSAGE_CONFIRM); + connectMessagingMessageRecord.userViewed = json.getString (META_MESSAGE_USER_VIEWED); + + return connectMessagingMessageRecord; + } + + public int getMessageId() { + return messageId; + } + + public void setMessageId(int messageId) { + this.messageId = messageId; + } + + public int getChannelId() { + return channelId; + } + + public void setChannelId(int channelId) { + this.channelId = channelId; + } + + public String getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getIsOutgoing() { + return isOutgoing; + } + + public void setIsOutgoing(String isOutgoing) { + this.isOutgoing = isOutgoing; + } + + public String getConfirmed() { + return confirmed; + } + + public void setConfirmed(String confirmed) { + this.confirmed = confirmed; + } + + public String getUserViewed() { + return userViewed; + } + + public void setUserViewed(String userViewed) { + this.userViewed = userViewed; + } +} diff --git a/app/src/org/commcare/connect/MessageManager.java b/app/src/org/commcare/connect/MessageManager.java new file mode 100644 index 000000000..1da2dd9e1 --- /dev/null +++ b/app/src/org/commcare/connect/MessageManager.java @@ -0,0 +1,14 @@ +package org.commcare.connect; + +public class MessageManager { + + private static MessageManager manager = null; + + public static MessageManager getInstance() { + if (manager == null) { + manager = new MessageManager(); + } + + return manager; + } +} diff --git a/app/src/org/commcare/models/database/connect/ConnectDatabaseUpgrader.java b/app/src/org/commcare/models/database/connect/ConnectDatabaseUpgrader.java index 34a2bc6a8..30e2bfd7f 100644 --- a/app/src/org/commcare/models/database/connect/ConnectDatabaseUpgrader.java +++ b/app/src/org/commcare/models/database/connect/ConnectDatabaseUpgrader.java @@ -20,6 +20,8 @@ import org.commcare.android.database.connect.models.ConnectLinkedAppRecordV3; import org.commcare.android.database.connect.models.ConnectLinkedAppRecordV8; import org.commcare.android.database.connect.models.ConnectLinkedAppRecordV9; +import org.commcare.android.database.connect.models.ConnectMessagingChannelRecord; +import org.commcare.android.database.connect.models.ConnectMessagingMessageRecord; import org.commcare.android.database.connect.models.ConnectPaymentUnitRecord; import org.commcare.android.database.connect.models.ConnectUserRecord; import org.commcare.android.database.connect.models.ConnectUserRecordV5; @@ -81,6 +83,11 @@ public void upgrade(SQLiteDatabase db, int oldVersion, int newVersion) { upgradeNineTen(db); oldVersion = 10; } + + if (oldVersion == 10) { + upgradeTenEleven(db); + oldVersion = 11; + } } private void upgradeOneTwo(SQLiteDatabase db) { @@ -432,6 +439,11 @@ private void upgradeNineTen(SQLiteDatabase db) { } } + private void upgradeTenEleven(SQLiteDatabase db) { + addTableForNewModel(db, ConnectMessagingChannelRecord.STORAGE_KEY, new ConnectMessagingChannelRecord()); + addTableForNewModel(db, ConnectMessagingMessageRecord.STORAGE_KEY, new ConnectMessagingMessageRecord()); + } + private static void addTableForNewModel(SQLiteDatabase db, String storageKey, Persistable modelToAdd) { db.beginTransaction(); diff --git a/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java b/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java index ef010c4fd..5658df162 100644 --- a/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java +++ b/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java @@ -14,6 +14,8 @@ import org.commcare.android.database.connect.models.ConnectJobRecord; import org.commcare.android.database.connect.models.ConnectLearnModuleSummaryRecord; import org.commcare.android.database.connect.models.ConnectLinkedAppRecord; +import org.commcare.android.database.connect.models.ConnectMessagingChannelRecord; +import org.commcare.android.database.connect.models.ConnectMessagingMessageRecord; import org.commcare.android.database.connect.models.ConnectPaymentUnitRecord; import org.commcare.android.database.connect.models.ConnectUserRecord; import org.commcare.logging.DataChangeLog; @@ -45,7 +47,7 @@ public class DatabaseConnectOpenHelper extends SQLiteOpenHelper { * V.9 - Added using_local_passphrase to ConnectLinkedAppRecord * V.10 - Added last_accessed column to ConnectLinkedAppRecord */ - private static final int CONNECT_DB_VERSION = 10; + private static final int CONNECT_DB_VERSION = 11; private static final String CONNECT_DB_LOCATOR = "database_connect"; @@ -112,6 +114,12 @@ public void onCreate(SQLiteDatabase database) { builder = new TableBuilder(ConnectPaymentUnitRecord.class); database.execSQL(builder.getTableCreateString()); + builder = new TableBuilder(ConnectMessagingChannelRecord.class); + database.execSQL(builder.getTableCreateString()); + + builder = new TableBuilder(ConnectMessagingMessageRecord.class); + database.execSQL(builder.getTableCreateString()); + DbUtil.createNumbersTable(database); database.setVersion(CONNECT_DB_VERSION); From fe368a947ba85c9373ac19c8398023dc2688e7e2 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Mon, 7 Oct 2024 12:41:43 +0530 Subject: [PATCH 2/3] Retrieve Message API Integration Retrieve Message API Integration --- app/AndroidManifest.xml | 138 ++++++++---------- app/res/drawable/ic_connect_menu_3_dot.xml | 13 ++ .../drawable/ic_connect_menu_notification.xml | 13 ++ app/res/drawable/ic_connect_menu_search.xml | 10 ++ app/res/layout/activity_connect_messaging.xml | 22 +++ app/res/layout/fragment_channel_list.xml | 14 ++ app/res/layout/item_channel.xml | 79 ++++++++++ app/res/menu/menu_connect_messaging.xml | 20 +++ .../nav_graph_connect_messaging.xml | 13 ++ .../connect/ConnectMessagingActivity.java | 115 +++++++++++++++ .../org/commcare/adapters/ChannelAdapter.java | 47 ++++++ .../connectMessaging/ChannelListFragment.java | 48 ++++++ .../connect/DatabaseConnectOpenHelper.java | 1 + 13 files changed, 459 insertions(+), 74 deletions(-) create mode 100644 app/res/drawable/ic_connect_menu_3_dot.xml create mode 100644 app/res/drawable/ic_connect_menu_notification.xml create mode 100644 app/res/drawable/ic_connect_menu_search.xml create mode 100644 app/res/layout/activity_connect_messaging.xml create mode 100644 app/res/layout/fragment_channel_list.xml create mode 100644 app/res/layout/item_channel.xml create mode 100644 app/res/menu/menu_connect_messaging.xml create mode 100644 app/res/navigation/nav_graph_connect_messaging.xml create mode 100644 app/src/org/commcare/activities/connect/ConnectMessagingActivity.java create mode 100644 app/src/org/commcare/adapters/ChannelAdapter.java create mode 100644 app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index da9698ed6..008ccf440 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -1,16 +1,17 @@ - + + - - - + @@ -55,15 +55,10 @@ android:name="android.hardware.camera" android:required="false" /> - - - - + android:protectionLevel="dangerous" /> + android:protectionLevel="dangerous" /> @@ -89,10 +83,12 @@ + + @@ -120,6 +116,15 @@ android:theme="@style/AppBaseTheme" android:usesCleartextTraffic="true" tools:replace="android:label,android:icon,android:theme, android:allowBackup"> + + + + + + + - + @@ -138,11 +143,7 @@ android:name="org.commcare.activities.DispatchActivity" android:exported="true" android:label="@string/application_name"> - - - - @@ -161,14 +162,13 @@ + android:windowSoftInputMode="adjustResize" /> + android:label="CommCare Forced Closure" /> - @@ -209,13 +209,13 @@ + android:theme="@style/PreferenceTheme" /> + android:theme="@style/PreferenceTheme" /> + android:theme="@style/FullscreenTheme" /> @@ -225,7 +225,7 @@ - + + android:windowSoftInputMode="adjustResize" /> + android:windowSoftInputMode="adjustResize" /> - + android:windowSoftInputMode="stateUnchanged|adjustResize" /> + + android:windowSoftInputMode="adjustResize" /> + android:windowSoftInputMode="adjustResize" /> + android:enabled="true" /> + android:windowSoftInputMode="adjustResize" /> + android:windowSoftInputMode="adjustResize" /> + android:windowSoftInputMode="adjustResize" /> + android:windowSoftInputMode="adjustResize" /> + android:windowSoftInputMode="adjustResize" /> - - - + android:windowSoftInputMode="adjustResize" /> + - + android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> - - - - - + + + + @@ -362,9 +358,9 @@ android:name="com.google.android.maps" android:required="false" /> - + - + - + android:windowSoftInputMode="adjustResize" /> + @@ -410,20 +406,20 @@ android:exported="true"> + - + - @@ -473,17 +469,17 @@ - + + android:windowSoftInputMode="adjustPan" /> + android:windowSoftInputMode="adjustResize" /> - + android:screenOrientation="portrait" /> + - + android:windowSoftInputMode="stateVisible|adjustResize" /> + android:windowSoftInputMode="stateVisible|adjustResize" /> - - - + @@ -529,23 +522,20 @@ android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" /> - - - - + - - + --> - - diff --git a/app/res/drawable/ic_connect_menu_3_dot.xml b/app/res/drawable/ic_connect_menu_3_dot.xml new file mode 100644 index 000000000..cd15adea6 --- /dev/null +++ b/app/res/drawable/ic_connect_menu_3_dot.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/res/drawable/ic_connect_menu_notification.xml b/app/res/drawable/ic_connect_menu_notification.xml new file mode 100644 index 000000000..a17b7fb9d --- /dev/null +++ b/app/res/drawable/ic_connect_menu_notification.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/res/drawable/ic_connect_menu_search.xml b/app/res/drawable/ic_connect_menu_search.xml new file mode 100644 index 000000000..c7c2b636b --- /dev/null +++ b/app/res/drawable/ic_connect_menu_search.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/res/layout/activity_connect_messaging.xml b/app/res/layout/activity_connect_messaging.xml new file mode 100644 index 000000000..744f60fbb --- /dev/null +++ b/app/res/layout/activity_connect_messaging.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/res/layout/fragment_channel_list.xml b/app/res/layout/fragment_channel_list.xml new file mode 100644 index 000000000..027d509c6 --- /dev/null +++ b/app/res/layout/fragment_channel_list.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/res/layout/item_channel.xml b/app/res/layout/item_channel.xml new file mode 100644 index 000000000..893921e8e --- /dev/null +++ b/app/res/layout/item_channel.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + diff --git a/app/res/menu/menu_connect_messaging.xml b/app/res/menu/menu_connect_messaging.xml new file mode 100644 index 000000000..7ac1815e3 --- /dev/null +++ b/app/res/menu/menu_connect_messaging.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/res/navigation/nav_graph_connect_messaging.xml b/app/res/navigation/nav_graph_connect_messaging.xml new file mode 100644 index 000000000..97bc463af --- /dev/null +++ b/app/res/navigation/nav_graph_connect_messaging.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java b/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java new file mode 100644 index 000000000..4849ec4a9 --- /dev/null +++ b/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java @@ -0,0 +1,115 @@ +package org.commcare.activities.connect; + +import android.app.SearchManager; +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SearchView; +import androidx.core.content.ContextCompat; +import androidx.core.view.MenuItemCompat; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavController; +import androidx.navigation.fragment.NavHostFragment; +import androidx.navigation.ui.NavigationUI; + +import org.commcare.dalvik.R; +import org.commcare.fragments.connectMessaging.ChannelListFragment; + +public class ConnectMessagingActivity extends AppCompatActivity { + + public NavController controller; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_connect_messaging); + Window window = getWindow(); + window.setStatusBarColor(getResources().getColor(R.color.connect_status_bar_color)); + ColorDrawable colorDrawable = new ColorDrawable(getResources().getColor(R.color.connect_blue_color)); + getSupportActionBar().setBackgroundDrawable(colorDrawable); + setTitle("Messaging"); + getSupportActionBar().setTitle("Messaging"); + + NavHostFragment navHostFragment = + (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_connect_messaging); + controller = navHostFragment.getNavController(); + NavigationUI.setupActionBarWithNavController(this, controller); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_connect_messaging, menu); + MenuItem searchItem = menu.findItem(R.id.action_search); + + if (searchItem != null) { + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); + + searchView.setOnCloseListener(new SearchView.OnCloseListener() { + @Override + public boolean onClose() { + return false; + } + }); + + EditText searchPlate = searchView.findViewById(androidx.appcompat.R.id.search_src_text); + searchPlate.setHint("Search"); + + View searchPlateView = searchView.findViewById(androidx.appcompat.R.id.search_plate); + searchPlateView.setBackgroundColor(ContextCompat.getColor(this, android.R.color.transparent)); + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + // Do your logic here + Toast.makeText(getApplicationContext(), query, Toast.LENGTH_SHORT).show(); + sendSearchQueryToFragment(query); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + return false; + } + }); + + SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); + searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + } + + return super.onCreateOptionsMenu(menu); + } + + public void sendSearchQueryToFragment(String query) { + NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_connect_messaging); + if (navHostFragment != null) { + Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0); + if (currentFragment instanceof ChannelListFragment) { + ((ChannelListFragment) currentFragment).onSearchQueryReceived(query); + } + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + return switch (id) { + case R.id.action_notification -> true; + default -> super.onOptionsItemSelected(item); + }; + } + + @Override + public boolean onSupportNavigateUp() { + NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_connect_messaging); + return navHostFragment.getNavController().navigateUp() || super.onSupportNavigateUp(); + } +} diff --git a/app/src/org/commcare/adapters/ChannelAdapter.java b/app/src/org/commcare/adapters/ChannelAdapter.java new file mode 100644 index 000000000..0951e18f0 --- /dev/null +++ b/app/src/org/commcare/adapters/ChannelAdapter.java @@ -0,0 +1,47 @@ +package org.commcare.adapters; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import org.commcare.dalvik.databinding.ItemChannelBinding; + +public class ChannelAdapter extends RecyclerView.Adapter { + + + public ChannelAdapter() { + } + + @NonNull + @Override + public ChannelViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ChannelViewHolder(ItemChannelBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ChannelViewHolder holder, int position) { + holder.bind(holder.binding); + } + + @Override + public int getItemCount() { + return 20; + } + + static class ChannelViewHolder extends RecyclerView.ViewHolder { + + private final ItemChannelBinding binding; + + public ChannelViewHolder(@NonNull ItemChannelBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind(ItemChannelBinding binding) { + binding.itemRootLayout.setOnClickListener(view -> {}); + } + } +} diff --git a/app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java b/app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java new file mode 100644 index 000000000..96f0a630f --- /dev/null +++ b/app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java @@ -0,0 +1,48 @@ +package org.commcare.fragments.connectMessaging; + +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import org.commcare.adapters.ChannelAdapter; +import org.commcare.dalvik.databinding.FragmentChannelListBinding; + +public class ChannelListFragment extends Fragment { + + private FragmentChannelListBinding binding; + + public static ChannelListFragment newInstance() { + ChannelListFragment fragment = new ChannelListFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentChannelListBinding.inflate(inflater, container, false); + View view = binding.getRoot(); + + binding.rvChannel.setLayoutManager(new LinearLayoutManager(getContext())); + ChannelAdapter channelAdapter = new ChannelAdapter(); + binding.rvChannel.setAdapter(channelAdapter); + + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + + public void onSearchQueryReceived(String query) { + } +} diff --git a/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java b/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java index 5658df162..624ce1cde 100644 --- a/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java +++ b/app/src/org/commcare/models/database/connect/DatabaseConnectOpenHelper.java @@ -46,6 +46,7 @@ public class DatabaseConnectOpenHelper extends SQLiteOpenHelper { * V.8 - Added is_user_suspended to ConnectJobRecord * V.9 - Added using_local_passphrase to ConnectLinkedAppRecord * V.10 - Added last_accessed column to ConnectLinkedAppRecord + * V.11 - Added ConnectMessagingChannelRecord table and ConnectMessagingMessageRecord table */ private static final int CONNECT_DB_VERSION = 11; From 4cc4882b8a9ddc0ff3571932cdae9b3494b0471a Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Wed, 9 Oct 2024 10:52:07 +0530 Subject: [PATCH 3/3] Created message screen UI Created message screen UI --- app/AndroidManifest.xml | 9 +- ...c_connect_message_editext_bg_24_border.xml | 9 ++ .../ic_connect_message_photo_camera.xml | 13 ++ app/res/drawable/ic_connect_message_read.xml | 10 ++ .../ic_connect_message_receiver_bg.xml | 9 ++ .../ic_connect_message_receiver_edge.xml | 9 ++ app/res/drawable/ic_connect_message_send.png | Bin 0 -> 3076 bytes .../drawable/ic_connect_message_sender_bg.xml | 9 ++ .../ic_connect_message_sender_edge.xml | 9 ++ .../ic_connect_message_speak_button.png | Bin 0 -> 3404 bytes .../drawable/ic_connect_message_unread.xml | 10 ++ app/res/layout/fragment_channel_list.xml | 2 +- app/res/layout/fragment_connect_message.xml | 72 ++++++++++ app/res/layout/item_channel.xml | 128 ++++++++++-------- app/res/layout/item_chat_left_view.xml | 63 +++++++++ app/res/layout/item_chat_right_view.xml | 79 +++++++++++ .../nav_graph_connect_messaging.xml | 14 +- app/res/values/colors.xml | 3 + app/res/values/strings.xml | 3 + .../connect/ConnectMessagingActivity.java | 7 +- .../org/commcare/adapters/ChannelAdapter.java | 19 ++- .../adapters/ConnectMessageAdapter.java | 83 ++++++++++++ .../connect/network/ApiConnectId.java | 6 + .../connectMessaging/ChannelListFragment.java | 48 ------- .../ConnectMessageChannelListFragment.java | 100 ++++++++++++++ .../ConnectMessageChatData.java | 59 ++++++++ .../ConnectMessageFragment.java | 91 +++++++++++++ 27 files changed, 741 insertions(+), 123 deletions(-) create mode 100644 app/res/drawable/ic_connect_message_editext_bg_24_border.xml create mode 100644 app/res/drawable/ic_connect_message_photo_camera.xml create mode 100644 app/res/drawable/ic_connect_message_read.xml create mode 100644 app/res/drawable/ic_connect_message_receiver_bg.xml create mode 100644 app/res/drawable/ic_connect_message_receiver_edge.xml create mode 100644 app/res/drawable/ic_connect_message_send.png create mode 100644 app/res/drawable/ic_connect_message_sender_bg.xml create mode 100644 app/res/drawable/ic_connect_message_sender_edge.xml create mode 100644 app/res/drawable/ic_connect_message_speak_button.png create mode 100644 app/res/drawable/ic_connect_message_unread.xml create mode 100644 app/res/layout/fragment_connect_message.xml create mode 100644 app/res/layout/item_chat_left_view.xml create mode 100644 app/res/layout/item_chat_right_view.xml create mode 100644 app/src/org/commcare/adapters/ConnectMessageAdapter.java delete mode 100644 app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java create mode 100644 app/src/org/commcare/fragments/connectMessaging/ConnectMessageChannelListFragment.java create mode 100644 app/src/org/commcare/fragments/connectMessaging/ConnectMessageChatData.java create mode 100644 app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index 008ccf440..b9ccdc7d1 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -119,11 +119,6 @@ - - - - - + + + + diff --git a/app/res/drawable/ic_connect_message_editext_bg_24_border.xml b/app/res/drawable/ic_connect_message_editext_bg_24_border.xml new file mode 100644 index 000000000..aa9c6891c --- /dev/null +++ b/app/res/drawable/ic_connect_message_editext_bg_24_border.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/res/drawable/ic_connect_message_photo_camera.xml b/app/res/drawable/ic_connect_message_photo_camera.xml new file mode 100644 index 000000000..8e30510cd --- /dev/null +++ b/app/res/drawable/ic_connect_message_photo_camera.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/res/drawable/ic_connect_message_read.xml b/app/res/drawable/ic_connect_message_read.xml new file mode 100644 index 000000000..2dfc3ea4d --- /dev/null +++ b/app/res/drawable/ic_connect_message_read.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/res/drawable/ic_connect_message_receiver_bg.xml b/app/res/drawable/ic_connect_message_receiver_bg.xml new file mode 100644 index 000000000..954f363de --- /dev/null +++ b/app/res/drawable/ic_connect_message_receiver_bg.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/res/drawable/ic_connect_message_receiver_edge.xml b/app/res/drawable/ic_connect_message_receiver_edge.xml new file mode 100644 index 000000000..34ea7b545 --- /dev/null +++ b/app/res/drawable/ic_connect_message_receiver_edge.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/res/drawable/ic_connect_message_send.png b/app/res/drawable/ic_connect_message_send.png new file mode 100644 index 0000000000000000000000000000000000000000..a3e2eeda17f77d847893e70ea057cc8a7ecf23ad GIT binary patch literal 3076 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 SZw|)*0000 + + + + \ No newline at end of file diff --git a/app/res/drawable/ic_connect_message_sender_edge.xml b/app/res/drawable/ic_connect_message_sender_edge.xml new file mode 100644 index 000000000..7360221b7 --- /dev/null +++ b/app/res/drawable/ic_connect_message_sender_edge.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/res/drawable/ic_connect_message_speak_button.png b/app/res/drawable/ic_connect_message_speak_button.png new file mode 100644 index 0000000000000000000000000000000000000000..9b7e422a1b488e9b30cc46405f5be1e0ef81a81f GIT binary patch literal 3404 zcmV-S4YTrzP)T86D4mpXYzhb6yyP48xd;&cS>v!XeH9VgP)L1QumX{aMOr;kKB=%d_}R z%KW2xjd~O_0hbZ-0GB0Q7Z5PGDXAZ z20%vksgz2&mh*WH7ekbkL)X2a-Z8j$TgfNrBJtwSYn>oH8)I zNx3-eXCe7gKw%e-mAsJPm>*M{uLOi1hjDp^0oxCR9ZA1=B;N=q(LZ@wQ*+!3hSFm_ z!{7rtE+9--oUb?!ei`%&4p|kA`Z^trIwl|-%Xz>TPD?ZD5Dn1LXw(q_nd3PT_7~+2 z<3KcnjzuF5ZKlV#Jjl76BJng8HNeWIdiv9CkLGQSK)wB!&rr&0E$aXG?BrPDB(#aP z2#8Wvo586hIeDNRDXrxKD%7vWfqGf(rY*jxr5=|f)x&?$)bt;So9|r71 zBUSvmOf;Eh-KgJG*A;=tH0y>k)yfayEK%@?X8|Sp-#ravn)O5Zp#^^Lw8vL@OJRjB z`*k3+MTo^dFAEtxMWDjG9ztUZD`ec?@AgJYU7;bC=${yJd$X$)MyV@oxbKy@ia<&{ zp3M~zWMq_a=4ybkW(1<>6JFdH>Y5RVMZlA(BJ=@wNU3#CRRO8!V=zfutb`TZUI+Is zsCG|P0jcOi-Y4YLib9S8qUb{)wW5%tfbyGJ5=8YVWZMf1d(Ug#x)rdecLQwte3$ur z`r5qunuD7+7a*(%0bA|Hg;v%3&DVqr8C{6nF|1cB1jHB*oq0ZfWV0*r6xmcrb)iG79JF34Gtpr* z&lpKAyt=dO+TFQDIG4NuZ@l%1`5X=P;PYEdb6v{begA;FcNZZ{JS0|aC_QbcJOXiH zK*+H3Gb6v7fj|BECfrftz^}Y{{%^&7D6Fut!0!!|J}(nc7}M9|+tyTEdwb$`#WfU> zm0~wPR7ke3^y!j-3}ZY>BhPv4(o)z`l@mBJUD_L463{}V%K(CKfq7P2fh7SkOK2hp zCm3JORLcTlv_zS3%W|+W1%%yqDH#cfa7(P{gG>Rj2t^;l8=vxd^GL3|fT;IHcqX5* zOaV#8b^t+mKv^DBGld95DU9$2V}%HW1BkTK2H_nUMI+7c!zzkCL|x3me2l9CY77XX z4pwrAb50v35cLz|%1y_BAnJl|Q7MdV0fMLlDdmQ?pP5SN0|VH?)hKif2%;Vsi&6w4 z8UkmD$3P>#dt@^lKf1Z>TJKjcgBNh}ymbbmbwa%xCjQ!8_Wa!F4S4yL8=w&}?IMuf z)YEE>|KUfKt4zPK_j483p0b%hfA!iNIAQm9>NqXd`>&PHxigomxQ3J8ryUyalFbBq zjAD20=9VVcKcfVN*R0^0c_-}Fnce(Iza`Py3FxX#qvEpVX@_WmQQ^w_|A$>AOPVoy zoO)p!oC0TXmBxov*2vqf_CQhUhIT2;u2FYYS?`Yg;@8(aMF+gMmY1&J@i3sm`@uweDjXwBySv}KKMnCZ&D4;B8#-(>|l|9D>J^am$ zRbPXC<_ACex9tMLA}9j9XZq@V)%UU!?CWoR3>uPUiT+7k3m*fGz{b1qYP_rwF)|%| zHsh)%ga&x~wzW$>277AnC_{b6#cOe`J#GPGHPPRCcB*RB3MknXjLBJ5Pz9YpkzfxB z_wy-&Vmf~0F&O#%OwHG0L*v(_iCf^6!v{B2h^Lm}4k}VYR#oG97BmD+t~J^mQjL4~ z;6`W_htzu?vPqSi4IY-E1SI|k8iK#^f4p$B;`$GtkCjEHW`XZHsNUPk%WCvl$LNDF zrXr9^VOh`={LQ~&({;u%o@PcOj6A1oHk`s9+c}M+4}h47Jht_Ci~-vZnvzihdg?2W zRP>6T+#QAW>mo4opZhA+)i=P0@A>`jeZkz}%nFJJdu(?#96Ve`j;Pdnr^qXDsxysMV)Uezq8)1<~6qn1JC_S+tgJA4`X4ttmjj{>NaQ& zis+@^J^>pYHig12I@ZN-v>3;Eu1$QEl9rY`w$4WO1Oe)>x4a;C6Rr z|2@&4z8!|OVYNimC|HN9HA<}yY&JdCy`i|YIRha88}{ILrp$Rc&BWZ4Q@!WW=l&TI z@tE_WP0bXSHop%c0zD6o3|A{#xB-QO?}2_t=dm6;RPWu?jG4#<$P5R)Mx$$ik>cm7 z3XctsmGiHE?NQhjf4JuBP&Cui^YC{17QFH1C$7pHIwA$6@X=IFSd6qAu>Q5D_mPTe zv1U(A6=|zYA`276!&l4{mP+;E#?e_IOo7FvY9XbPisNA`Ir2e7b(nVkzN5JVLOlxL|j0Z|$ws)6atdhl-LvYwnA0fMl>n!e0y)(iPj>8|Tx-nkX0 zZ&+8BVx>K-WeXDt+4OkNR_kTk0$8Gda!5Ud^5}2Ekz{(T=a}`P?aEYD=STuUl%O;* zY(FiE~5<=b$J= zNV!;5162h?Q7GKhiatoq{edV7g%>5DW3}$7DIhZnfqV^!u;JMAD#g_fWm2${>iaAZ zp}}d~$BHWf<(0^&Miv^xu$$0G#?`#PQEh~61x=#q``W2=Ho!TY2f}{{IF?TJ zB%z74WMf1Ukq>Esc#xKySg7)AQV1-(k|*jsstsBs9;BsPv+gz~;ww2Dr`}no$Q$Nn zdLAn+-`m&h;xibhc|>i-9Or?i^|qX7`Jub`0n9=jRq)$~8ewjSc#yX4E}rO5tC|ZN z1fqq=k@Q&N1hk2^9{Y_SOae{NZw+!*f;`zy@gN;J-++8klQC14JkXAmWu>DBWY9iD z%|MPkBvucV?ws0AI)1_mMWZ^&_p*-V=c#uN-yG3H(a0_6ADJ@BJwxCFe09bXMkB`L z5M%5p5EbAOb6h3d39sXXFAoVbg%pAFOo9P~xl4xn8t!zuvcuP>%qbxmN=T=}DkMJ( zr$``B_B6b!sf95dtfqA{doaLB(#P&q$r+rjEA)aT{NX=B_J!NX95{#Dnd!db}%X9t)JYcikhl6h3Bf{aq6qY zn%8s^j1{c~WCup6`*1%FT*Nq_5$9WE!H}yI7%SWsb9i~y{4OOPi + + diff --git a/app/res/layout/fragment_channel_list.xml b/app/res/layout/fragment_channel_list.xml index 027d509c6..3f0bb28b7 100644 --- a/app/res/layout/fragment_channel_list.xml +++ b/app/res/layout/fragment_channel_list.xml @@ -3,7 +3,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" - tools:context="org.commcare.fragments.connectMessaging.ChannelListFragment"> + tools:context="org.commcare.fragments.connectMessaging.ConnectMessageChannelListFragment"> + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/layout/item_channel.xml b/app/res/layout/item_channel.xml index 893921e8e..c69236576 100644 --- a/app/res/layout/item_channel.xml +++ b/app/res/layout/item_channel.xml @@ -4,76 +4,88 @@ android:layout_width="match_parent" android:id="@+id/itemRootLayout" android:layout_height="wrap_content" - android:orientation="vertical" - android:padding="8dp"> + android:background="?attr/selectableItemBackground" + android:orientation="vertical"> - + app:layout_constraintTop_toTopOf="parent"> - + - + - + - + + + + + + app:layout_constraintTop_toBottomOf="@+id/constraint" /> diff --git a/app/res/layout/item_chat_left_view.xml b/app/res/layout/item_chat_left_view.xml new file mode 100644 index 000000000..97773416c --- /dev/null +++ b/app/res/layout/item_chat_left_view.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/layout/item_chat_right_view.xml b/app/res/layout/item_chat_right_view.xml new file mode 100644 index 000000000..c95729b50 --- /dev/null +++ b/app/res/layout/item_chat_right_view.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/navigation/nav_graph_connect_messaging.xml b/app/res/navigation/nav_graph_connect_messaging.xml index 97bc463af..8633cda44 100644 --- a/app/res/navigation/nav_graph_connect_messaging.xml +++ b/app/res/navigation/nav_graph_connect_messaging.xml @@ -7,7 +7,17 @@ + tools:layout="@layout/fragment_channel_list" > + + + + \ No newline at end of file diff --git a/app/res/values/colors.xml b/app/res/values/colors.xml index 217cfaca4..174aca29d 100644 --- a/app/res/values/colors.xml +++ b/app/res/values/colors.xml @@ -171,4 +171,7 @@ #88BEE1 #16A085 #EA6944 + #5C6FD0 + #F1F5F9 + #334155 diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml index 79f3f4b01..7e0318ffe 100644 --- a/app/res/values/strings.xml +++ b/app/res/values/strings.xml @@ -43,6 +43,9 @@ https://connectid.dimagi.com/users/recover/initiate_deactivation https://connectid.dimagi.com/users/recover/confirm_deactivation + + https://connectid.dimagi.com/users/retrieve_messages + https://pact.dimagi.com/keys/getkey diff --git a/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java b/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java index 4849ec4a9..50e199340 100644 --- a/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java +++ b/app/src/org/commcare/activities/connect/ConnectMessagingActivity.java @@ -9,7 +9,6 @@ import android.view.View; import android.view.Window; import android.widget.EditText; -import android.widget.ImageView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; @@ -22,7 +21,7 @@ import androidx.navigation.ui.NavigationUI; import org.commcare.dalvik.R; -import org.commcare.fragments.connectMessaging.ChannelListFragment; +import org.commcare.fragments.connectMessaging.ConnectMessageChannelListFragment; public class ConnectMessagingActivity extends AppCompatActivity { @@ -92,8 +91,8 @@ public void sendSearchQueryToFragment(String query) { NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_connect_messaging); if (navHostFragment != null) { Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0); - if (currentFragment instanceof ChannelListFragment) { - ((ChannelListFragment) currentFragment).onSearchQueryReceived(query); + if (currentFragment instanceof ConnectMessageChannelListFragment) { + ((ConnectMessageChannelListFragment) currentFragment).onSearchQueryReceived(query); } } } diff --git a/app/src/org/commcare/adapters/ChannelAdapter.java b/app/src/org/commcare/adapters/ChannelAdapter.java index 0951e18f0..5a8e4328e 100644 --- a/app/src/org/commcare/adapters/ChannelAdapter.java +++ b/app/src/org/commcare/adapters/ChannelAdapter.java @@ -1,7 +1,6 @@ package org.commcare.adapters; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; @@ -11,8 +10,10 @@ public class ChannelAdapter extends RecyclerView.Adapter { + private final OnChannelClickListener clickListener; - public ChannelAdapter() { + public ChannelAdapter(OnChannelClickListener clickListener) { + this.clickListener = clickListener; } @NonNull @@ -23,7 +24,7 @@ public ChannelViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewT @Override public void onBindViewHolder(@NonNull ChannelViewHolder holder, int position) { - holder.bind(holder.binding); + holder.bind(holder.binding, position, clickListener); } @Override @@ -40,8 +41,16 @@ public ChannelViewHolder(@NonNull ItemChannelBinding binding) { this.binding = binding; } - public void bind(ItemChannelBinding binding) { - binding.itemRootLayout.setOnClickListener(view -> {}); + public void bind(ItemChannelBinding binding, int position, OnChannelClickListener clickListener) { + binding.itemRootLayout.setOnClickListener(view -> { + if (clickListener != null) { + clickListener.onChannelClick(position); + } + }); } } + + public interface OnChannelClickListener { + void onChannelClick(int position); + } } diff --git a/app/src/org/commcare/adapters/ConnectMessageAdapter.java b/app/src/org/commcare/adapters/ConnectMessageAdapter.java new file mode 100644 index 000000000..a15a4888f --- /dev/null +++ b/app/src/org/commcare/adapters/ConnectMessageAdapter.java @@ -0,0 +1,83 @@ +package org.commcare.adapters; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import org.commcare.dalvik.databinding.ItemChatLeftViewBinding; +import org.commcare.dalvik.databinding.ItemChatRightViewBinding; +import org.commcare.fragments.connectMessaging.ConnectMessageChatData; + +import java.util.ArrayList; + +public class ConnectMessageAdapter extends RecyclerView.Adapter { + + public static final int LEFTVIEW = 0; + public static final int RIGHTVIEW = 1; + ArrayList dummyData; + + public ConnectMessageAdapter(ArrayList dummyData) { + this.dummyData = dummyData; + } + + public static class LeftViewHolder extends RecyclerView.ViewHolder { + ItemChatLeftViewBinding binding; + + public LeftViewHolder(ItemChatLeftViewBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind() { + + } + } + + public static class RightViewHolder extends RecyclerView.ViewHolder { + ItemChatRightViewBinding binding; + + public RightViewHolder(ItemChatRightViewBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind() { + + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == LEFTVIEW) { + ItemChatLeftViewBinding binding = ItemChatLeftViewBinding.inflate( + LayoutInflater.from(parent.getContext()), parent, false); + return new LeftViewHolder(binding); + } else { + ItemChatRightViewBinding binding = ItemChatRightViewBinding.inflate( + LayoutInflater.from(parent.getContext()), parent, false); + return new RightViewHolder(binding); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (getItemViewType(position) == LEFTVIEW) { + ((LeftViewHolder) holder).bind(); + } else { + ((RightViewHolder) holder).bind(); + } + } + + @Override + public int getItemCount() { + return dummyData.size(); + } + + @Override + public int getItemViewType(int position) { + return dummyData.get(position).getType() == LEFTVIEW ? LEFTVIEW : RIGHTVIEW; + } +} diff --git a/app/src/org/commcare/connect/network/ApiConnectId.java b/app/src/org/commcare/connect/network/ApiConnectId.java index f330c3931..d252ab2b3 100644 --- a/app/src/org/commcare/connect/network/ApiConnectId.java +++ b/app/src/org/commcare/connect/network/ApiConnectId.java @@ -424,4 +424,10 @@ public static boolean confirmUserDeactivation(Context context, String phone, Str return ConnectNetworkHelper.post(context, context.getString(urlId), API_VERSION_CONNECT_ID, authInfo, params, false, false, callback); } + + public static boolean retrieveChannel(Context context,IApiCallback callback) { + return ConnectNetworkHelper.get(context, + context.getString(R.string.ConnectMessageRetrieveMessagesURL), + API_VERSION_CONNECT_ID, new AuthInfo.NoAuth(), null, false, callback); + } } diff --git a/app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java b/app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java deleted file mode 100644 index 96f0a630f..000000000 --- a/app/src/org/commcare/fragments/connectMessaging/ChannelListFragment.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.commcare.fragments.connectMessaging; - -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; - -import org.commcare.adapters.ChannelAdapter; -import org.commcare.dalvik.databinding.FragmentChannelListBinding; - -public class ChannelListFragment extends Fragment { - - private FragmentChannelListBinding binding; - - public static ChannelListFragment newInstance() { - ChannelListFragment fragment = new ChannelListFragment(); - Bundle args = new Bundle(); - fragment.setArguments(args); - return fragment; - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - binding = FragmentChannelListBinding.inflate(inflater, container, false); - View view = binding.getRoot(); - - binding.rvChannel.setLayoutManager(new LinearLayoutManager(getContext())); - ChannelAdapter channelAdapter = new ChannelAdapter(); - binding.rvChannel.setAdapter(channelAdapter); - - return view; - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; - } - - public void onSearchQueryReceived(String query) { - } -} diff --git a/app/src/org/commcare/fragments/connectMessaging/ConnectMessageChannelListFragment.java b/app/src/org/commcare/fragments/connectMessaging/ConnectMessageChannelListFragment.java new file mode 100644 index 000000000..4550eb8cb --- /dev/null +++ b/app/src/org/commcare/fragments/connectMessaging/ConnectMessageChannelListFragment.java @@ -0,0 +1,100 @@ +package org.commcare.fragments.connectMessaging; + +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavDirections; +import androidx.navigation.Navigation; +import androidx.recyclerview.widget.LinearLayoutManager; + +import org.commcare.adapters.ChannelAdapter; +import org.commcare.connect.network.ApiConnectId; +import org.commcare.connect.network.IApiCallback; +import org.commcare.dalvik.R; +import org.commcare.dalvik.databinding.FragmentChannelListBinding; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; + +public class ConnectMessageChannelListFragment extends Fragment { + + private FragmentChannelListBinding binding; + + public static ConnectMessageChannelListFragment newInstance() { + ConnectMessageChannelListFragment fragment = new ConnectMessageChannelListFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentChannelListBinding.inflate(inflater, container, false); + View view = binding.getRoot(); + + binding.rvChannel.setLayoutManager(new LinearLayoutManager(getContext())); + ChannelAdapter channelAdapter = new ChannelAdapter(position -> { + NavDirections directions; + directions = ConnectMessageChannelListFragmentDirections.actionChannelListFragmentToConnectMessageFragment(); + Navigation.findNavController(binding.rvChannel).navigate(directions); + }); + binding.rvChannel.setAdapter(channelAdapter); +// retrieveChannel(); + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + + public void onSearchQueryReceived(String query) { + } + + public void retrieveChannel() { + IApiCallback callback = new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + Log.e("DEBUG_TESTING", "processSuccess: "); + } + + @Override + public void processFailure(int responseCode, IOException e) { + Log.e("DEBUG_TESTING", "processFailure: " + responseCode); + String message = ""; + if (responseCode > 0) { + message = String.format(Locale.getDefault(), "(%d)", responseCode); + } else if (e != null) { + message = e.toString(); + } + } + + @Override + public void processNetworkFailure() { + Log.e("DEBUG_TESTING", "processNetworkFailure: "); + } + + @Override + public void processOldApiError() { + Log.e("DEBUG_TESTING", "processOldApiError: "); + } + }; + + boolean isBusy; + + isBusy = !ApiConnectId.retrieveChannel(requireActivity(), callback); + + if (isBusy) { + Toast.makeText(requireActivity(), R.string.busy_message, Toast.LENGTH_SHORT).show(); + } + } +} diff --git a/app/src/org/commcare/fragments/connectMessaging/ConnectMessageChatData.java b/app/src/org/commcare/fragments/connectMessaging/ConnectMessageChatData.java new file mode 100644 index 000000000..819ee4957 --- /dev/null +++ b/app/src/org/commcare/fragments/connectMessaging/ConnectMessageChatData.java @@ -0,0 +1,59 @@ +package org.commcare.fragments.connectMessaging; + +public class ConnectMessageChatData { + + private int type; + private String message; + private String userName; + private int countUnread; + private boolean isMessageRead; + + // Constructor with parameters + public ConnectMessageChatData(int type, String message, String userName, boolean isMessageRead) { + this.type = type; + this.message = message; + this.userName = userName; + this.isMessageRead = isMessageRead; + } + + // Getters and setters + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public int getCountUnread() { + return countUnread; + } + + public void setCountUnread(int countUnread) { + this.countUnread = countUnread; + } + + public boolean isMessageRead() { + return isMessageRead; + } + + public void setMessageRead(boolean messageRead) { + isMessageRead = messageRead; + } +} diff --git a/app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java b/app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java new file mode 100644 index 000000000..41d9e7409 --- /dev/null +++ b/app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java @@ -0,0 +1,91 @@ +package org.commcare.fragments.connectMessaging; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import org.commcare.adapters.ConnectMessageAdapter; +import org.commcare.dalvik.R; +import org.commcare.dalvik.databinding.FragmentConnectMessageBinding; + +import java.util.ArrayList; + +public class ConnectMessageFragment extends Fragment { + + private FragmentConnectMessageBinding binding; + + public static ConnectMessageFragment newInstance(String param1, String param2) { + ConnectMessageFragment fragment = new ConnectMessageFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentConnectMessageBinding.inflate(inflater, container, false); + handleSendButtonListener(); + setChatAdapter(); + return binding.getRoot(); + } + + private void handleSendButtonListener() { + binding.etMessage.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (s.length() > 0) { + binding.imgSendMessage.setVisibility(View.VISIBLE); +// binding.etMessage.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); // Remove drawableEnd + } else { + binding.imgSendMessage.setVisibility(View.GONE); +// binding.etMessage.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_connect_message_photo_camera, 0); // Add back drawableEnd + } + } + + @Override + public void afterTextChanged(Editable s) { + } + }); + } + + private void setChatAdapter() { + ConnectMessageAdapter connectMessageAdapter = new ConnectMessageAdapter(getDummyData()); + binding.rvChat.setAdapter(connectMessageAdapter); + } + + public static ArrayList getDummyData() { + ArrayList dataList = new ArrayList<>(); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "I commented on Figma, I want to add some fancy icons. Do you have any icon set?", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "I am in a process of designing some. When do you need them?", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Hi! Are you there", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "Yes", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Do you want to go out", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "Sorry I am busy!!", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "I commented on Figma, I want to add some fancy icons. Do you have any icon set?", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "I am in a process of designing some. When do you need them?", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Hi! Are you there", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "Yes", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Do you want to go out", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "Sorry I am busy!!", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "I commented on Figma, I want to add some fancy icons. Do you have any icon set?", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "I am in a process of designing some. When do you need them?", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Hi! Are you there", "@Esther", true)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.LEFTVIEW, "Yes", "@Jane", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Do you want to go out", "@Esther", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Do you want to go out", "@Esther", false)); + dataList.add(new ConnectMessageChatData(ConnectMessageAdapter.RIGHTVIEW, "Do you want to go out", "@Esther", false)); + return dataList; + } +} +