diff --git a/app/build.gradle b/app/build.gradle index 6b82c7e618..df1eba7c95 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,9 +8,9 @@ android { defaultConfig { applicationId "org.ole.planet.myplanet" minSdkVersion 21 - targetSdkVersion 34 - versionCode 1613 - versionName "0.16.13" + targetSdkVersion 34 + versionCode 1616 + versionName "0.16.16" ndkVersion '21.3.6528147' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt index 9fa7aaf3d9..34cc5055d2 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmChatHistory.kt @@ -15,8 +15,9 @@ open class RealmChatHistory : RealmObject() { var _id: String? = null var _rev: String? = null var user: String? = null + var aiProvider: String? = null var title: String? = null - var updatedTime: String? = null + var createdDate: String? = null var conversations: RealmList? = null companion object { @JvmStatic @@ -31,8 +32,9 @@ open class RealmChatHistory : RealmObject() { chatHistory._rev = JsonUtils.getString("_rev", act) chatHistory._id = JsonUtils.getString("_id", act) chatHistory.title = JsonUtils.getString("title", act) - chatHistory.updatedTime = JsonUtils.getString("updatedTime", act) + chatHistory.createdDate = JsonUtils.getString("createdDate", act) chatHistory.user = JsonUtils.getString("user", act) + chatHistory.aiProvider = JsonUtils.getString("aiProvider", act) chatHistory.conversations = parseConversations(mRealm, JsonUtils.getJsonArray("conversations", act)) mRealm.commitTransaction() } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt index 6a2cbecd9e..a7e78fd765 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmNews.kt @@ -4,6 +4,7 @@ import android.text.TextUtils import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject +import com.google.gson.JsonSyntaxException import io.realm.Realm import io.realm.RealmList import io.realm.RealmObject @@ -70,6 +71,7 @@ open class RealmNews : RealmObject() { val imagesArray: JsonArray get() = if (images == null) JsonArray() else Gson().fromJson(images, JsonArray::class.java) + val labelsArray: JsonArray get() { val array = JsonArray() @@ -100,17 +102,14 @@ open class RealmNews : RealmObject() { } return ms } + val isCommunityNews: Boolean get() { val array = Gson().fromJson(viewIn, JsonArray::class.java) var isCommunity = false for (e in array) { val `object` = e.asJsonObject - if (`object`.has("section") && `object`["section"].asString.equals( - "community", - ignoreCase = true - ) - ) { + if (`object`.has("section") && `object`["section"].asString.equals("community", ignoreCase = true)) { isCommunity = true break } @@ -121,9 +120,7 @@ open class RealmNews : RealmObject() { companion object { @JvmStatic fun insert(mRealm: Realm, doc: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } + if (!mRealm.isInTransaction) mRealm.beginTransaction() var news = mRealm.where(RealmNews::class.java) .equalTo("_id", JsonUtils.getString("_id", doc)) .findFirst() @@ -214,8 +211,11 @@ open class RealmNews : RealmObject() { @JvmStatic fun createNews(map: HashMap, mRealm: Realm, user: RealmUserModel?, imageUrls: RealmList?): RealmNews { - if (!mRealm.isInTransaction) mRealm.beginTransaction() - val news = mRealm.createObject(RealmNews::class.java, UUID.randomUUID().toString()) + if (!mRealm.isInTransaction) { + mRealm.beginTransaction() + } + + val news = mRealm.createObject(RealmNews::class.java, "${UUID.randomUUID()}") news.message = map["message"] news.time = Date().time news.createdOn = user?.planetCode @@ -226,19 +226,59 @@ open class RealmNews : RealmObject() { news.messagePlanetCode = map["messagePlanetCode"] news.messageType = map["messageType"] news.viewIn = getViewInJson(map) + news.chat = map["chat"]?.toBoolean() ?: false + try { - news.updatedDate = map["updatedDate"]?.toLong()!! + news.updatedDate = map["updatedDate"]?.toLong() ?: 0 } catch (e: Exception) { e.printStackTrace() } + news.userId = user?.id - news.replyTo = if (map.containsKey("replyTo")) { - map["replyTo"] - } else { - "" - } + news.replyTo = map["replyTo"] ?: "" news.user = Gson().toJson(user?.serialize()) news.imageUrls = imageUrls + + if (map.containsKey("news")) { + val newsObj = map["news"] + val gson = Gson() + try { + val newsJsonString = newsObj?.replace("=", ":") + val newsJson = gson.fromJson(newsJsonString, JsonObject::class.java) + news.newsId = JsonUtils.getString("_id", newsJson) + news.newsRev = JsonUtils.getString("_rev", newsJson) + news.newsUser = JsonUtils.getString("user", newsJson) + news.aiProvider = JsonUtils.getString("aiProvider", newsJson) + news.newsTitle = JsonUtils.getString("title", newsJson) + if (newsJson.has("conversations")) { + val conversationsElement = newsJson.get("conversations") + if (conversationsElement.isJsonPrimitive && conversationsElement.asJsonPrimitive.isString) { + val conversationsString = conversationsElement.asString + try { + val conversationsArray = gson.fromJson(conversationsString, JsonArray::class.java) + if (conversationsArray.size() > 0) { + val conversationsList = ArrayList>() + conversationsArray.forEach { conversationElement -> + val conversationObj = conversationElement.asJsonObject + val conversationMap = HashMap() + conversationMap["query"] = conversationObj.get("query").asString + conversationMap["response"] = conversationObj.get("response").asString + conversationsList.add(conversationMap) + } + news.conversations = Gson().toJson(conversationsList) + } + } catch (e: JsonSyntaxException) { + e.printStackTrace() + } + } + } + news.newsCreatedDate = JsonUtils.getLong("createdDate", newsJson) + news.newsUpdatedDate = JsonUtils.getLong("updatedDate", newsJson) + } catch (e: JsonSyntaxException) { + e.printStackTrace() + } + } + mRealm.commitTransaction() return news } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt index 83807e32a7..96f74009de 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/chat/ChatHistoryListAdapter.kt @@ -1,69 +1,222 @@ package org.ole.planet.myplanet.ui.chat +import android.app.AlertDialog import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.google.gson.Gson +import io.realm.Realm import io.realm.RealmList +import org.ole.planet.myplanet.R +import org.ole.planet.myplanet.databinding.AddNoteDialogBinding +import org.ole.planet.myplanet.databinding.ChatShareDialogBinding +import org.ole.planet.myplanet.databinding.GrandChildRecyclerviewDialogBinding import org.ole.planet.myplanet.databinding.RowChatHistoryBinding +import org.ole.planet.myplanet.datamanager.DatabaseService import org.ole.planet.myplanet.model.Conversation import org.ole.planet.myplanet.model.RealmChatHistory +import org.ole.planet.myplanet.model.RealmMyTeam +import org.ole.planet.myplanet.model.RealmNews.Companion.createNews +import org.ole.planet.myplanet.model.RealmUserModel +import org.ole.planet.myplanet.service.UserProfileDbHandler +import org.ole.planet.myplanet.ui.news.ExpandableListAdapter +import org.ole.planet.myplanet.ui.news.GrandChildAdapter +import org.ole.planet.myplanet.ui.team.BaseTeamFragment.Companion.settings +import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME +import java.util.Date class ChatHistoryListAdapter(var context: Context, private var chatHistory: List) : RecyclerView.Adapter() { - private lateinit var rowChatHistoryBinding: RowChatHistoryBinding - private var chatHistoryItemClickListener: ChatHistoryItemClickListener? = null - private var filteredChatHistory: List = chatHistory - var chatTitle: String? = "" - interface ChatHistoryItemClickListener { - fun onChatHistoryItemClicked(conversations: RealmList?, _id: String, _rev: String?) - } + private lateinit var rowChatHistoryBinding: RowChatHistoryBinding + private var chatHistoryItemClickListener: ChatHistoryItemClickListener? = null + private var filteredChatHistory: List = chatHistory + private var chatTitle: String? = "" + private lateinit var expandableListAdapter: ExpandableListAdapter + private lateinit var expandableTitleList: List + private lateinit var expandableDetailList: HashMap> + private lateinit var mRealm: Realm + var user: RealmUserModel? = null - fun setChatHistoryItemClickListener(listener: ChatHistoryItemClickListener) { - chatHistoryItemClickListener = listener - } + interface ChatHistoryItemClickListener { + fun onChatHistoryItemClicked(conversations: RealmList?, _id: String, _rev: String?) + } - fun filter(query: String) { - filteredChatHistory = chatHistory.filter { chat -> - if (chat.conversations != null && chat.conversations?.isNotEmpty() == true) { - chat.conversations!![0]?.query?.contains(query, ignoreCase = true) == true - } else { - chat.title?.contains(query, ignoreCase = true) ==true + fun setChatHistoryItemClickListener(listener: ChatHistoryItemClickListener) { + chatHistoryItemClickListener = listener + } + + fun filter(query: String) { + filteredChatHistory = chatHistory.filter { chat -> + if (chat.conversations != null && chat.conversations?.isNotEmpty() == true) { + chat.conversations?.get(0)?.query?.contains(query, ignoreCase = true) == true + } else { + chat.title?.contains(query, ignoreCase = true) ==true + } } + notifyDataSetChanged() } - notifyDataSetChanged() - } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { rowChatHistoryBinding = RowChatHistoryBinding.inflate(LayoutInflater.from(parent.context), parent, false) + mRealm = DatabaseService(context).realmInstance + user = UserProfileDbHandler(context).userModel return ViewHolderChat(rowChatHistoryBinding) } - override fun getItemCount(): Int { - return filteredChatHistory.size - } + override fun getItemCount(): Int { + return filteredChatHistory.size + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val viewHolderChat = holder as ViewHolderChat + if (filteredChatHistory[position].conversations != null && filteredChatHistory[position].conversations?.isNotEmpty() == true) { + viewHolderChat.rowChatHistoryBinding.chatTitle.text = filteredChatHistory[position].conversations?.get(0)?.query + viewHolderChat.rowChatHistoryBinding.chatTitle.contentDescription = filteredChatHistory[position].conversations?.get(0)?.query + chatTitle = filteredChatHistory[position].conversations?.get(0)?.query + } else { + viewHolderChat.rowChatHistoryBinding.chatTitle.text = filteredChatHistory[position].title + viewHolderChat.rowChatHistoryBinding.chatTitle.contentDescription = filteredChatHistory[position].title + chatTitle = filteredChatHistory[position].title + } + + viewHolderChat.rowChatHistoryBinding.root.setOnClickListener { + viewHolderChat.rowChatHistoryBinding.chatCardView.contentDescription = chatTitle + chatHistoryItemClickListener?.onChatHistoryItemClicked( + filteredChatHistory[position].conversations, + "${filteredChatHistory[position]._id}", + filteredChatHistory[position]._rev + ) + } + + viewHolderChat.rowChatHistoryBinding.shareChat.setOnClickListener { + val chatShareDialogBinding = ChatShareDialogBinding.inflate(LayoutInflater.from(context)) + var dialog: AlertDialog? = null - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - val viewHolderChat = holder as ViewHolderChat - if (filteredChatHistory[position].conversations != null && filteredChatHistory[position].conversations?.isNotEmpty() == true) { - viewHolderChat.rowChatHistoryBinding.chatTitle.text = filteredChatHistory[position].conversations?.get(0)?.query - viewHolderChat.rowChatHistoryBinding.chatTitle.contentDescription = filteredChatHistory[position].conversations?.get(0)?.query - chatTitle = filteredChatHistory[position].conversations?.get(0)?.query - } else { - viewHolderChat.rowChatHistoryBinding.chatTitle.text = filteredChatHistory[position].title - viewHolderChat.rowChatHistoryBinding.chatTitle.contentDescription = filteredChatHistory[position].title - chatTitle = filteredChatHistory[position].title + expandableDetailList = getData() as HashMap> + expandableTitleList = ArrayList(expandableDetailList.keys) + expandableListAdapter = ExpandableListAdapter(context, expandableTitleList, expandableDetailList) + chatShareDialogBinding.listView.setAdapter(expandableListAdapter) + + chatShareDialogBinding.listView.setOnChildClickListener { _, _, groupPosition, childPosition, id -> + if (expandableTitleList[groupPosition] == "share with team/enterprise") { + val teamList = mRealm.where(RealmMyTeam::class.java) + .isEmpty("teamId").notEqualTo("status", "archived") + .equalTo("type", "team").findAll() + + val enterpriseList = mRealm.where(RealmMyTeam::class.java) + .isEmpty("teamId").notEqualTo("status", "archived") + .equalTo("type", "enterprise").findAll() + + if (expandableDetailList[expandableTitleList[groupPosition]]?.get(childPosition) == "teams") { + showGrandChildRecyclerView(teamList, "teams", filteredChatHistory[position]) + } else { + showGrandChildRecyclerView(enterpriseList, "enterprises", filteredChatHistory[position]) + } + } else { + settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + val sParentcode = settings?.getString("parentCode", "") + val communityName = settings?.getString("communityName", "") + val teamId = "$communityName@$sParentcode" + val community = mRealm.where(RealmMyTeam::class.java).equalTo("_id", teamId).findFirst() + showEditTextAndShareButton(community, "community", filteredChatHistory[position]) + } + dialog?.dismiss() + false + } + + val builder = AlertDialog.Builder(context) + builder.setView(chatShareDialogBinding.root) + builder.setPositiveButton(context.getString(R.string.close)) { _, _ -> + dialog?.dismiss() + } + dialog = builder.create() + dialog.show() + } } - viewHolderChat.rowChatHistoryBinding.root.setOnClickListener { - viewHolderChat.rowChatHistoryBinding.chatCardView.contentDescription = chatTitle - chatHistoryItemClickListener?.onChatHistoryItemClicked( - filteredChatHistory[position].conversations, - "${filteredChatHistory[position]._id}", - filteredChatHistory[position]._rev - ) + private fun showGrandChildRecyclerView(items: List, section: String, realmChatHistory: RealmChatHistory) { + val grandChildDialogBinding = GrandChildRecyclerviewDialogBinding.inflate(LayoutInflater.from(context)) + var dialog: AlertDialog? = null + + if (section == "teams") { + grandChildDialogBinding.title.text = context.getString(R.string.team) + } else { + grandChildDialogBinding.title.text = context.getString(R.string.enterprises) + } + val grandChildAdapter = GrandChildAdapter(items) { selectedItem -> + showEditTextAndShareButton(selectedItem, "teams", realmChatHistory) + dialog?.dismiss() + } + grandChildDialogBinding.recyclerView.layoutManager = LinearLayoutManager(context) + grandChildDialogBinding.recyclerView.adapter = grandChildAdapter + + val builder = AlertDialog.Builder(context) + builder.setView(grandChildDialogBinding.root) + builder.setPositiveButton("close") { _, _ -> + dialog?.dismiss() + } + dialog = builder.create() + dialog.show() + } + + private fun showEditTextAndShareButton(team: RealmMyTeam? = null, section: String, chatHistory: RealmChatHistory) { + val addNoteDialogBinding = AddNoteDialogBinding.inflate(LayoutInflater.from(context)) + val builder = AlertDialog.Builder(context) + builder.setView(addNoteDialogBinding.root) + builder.setPositiveButton(context.getString(R.string.share_chat)) { dialog, _ -> + val serializedConversations = chatHistory.conversations?.map { serializeConversation(it) } + val serializedMap = HashMap() + serializedMap["_id"] = chatHistory._id ?: "" + serializedMap["_rev"] = chatHistory._rev ?: "" + serializedMap["title"] = "${chatHistory.title}".trim() + serializedMap["user"] = chatHistory.user ?: "" + serializedMap["aiProvider"] = chatHistory.aiProvider ?: "" + serializedMap["createdDate"] = "${Date().time}" + serializedMap["updatedDate"] = "${Date().time}" + serializedMap["conversations"] = Gson().toJson(serializedConversations) + + val map = HashMap() + map["message"] = "${addNoteDialogBinding.editText.text}" + map["viewInId"] = team?._id ?: "" + map["viewInSection"] = section + map["messageType"] = team?.teamType ?: "" + map["messagePlanetCode"] = team?.teamPlanetCode ?: "" + map["chat"] = "true" + map["news"] = Gson().toJson(serializedMap) + + createNews(map, mRealm, user, null) + dialog.dismiss() } + builder.setNegativeButton(context.getString(R.string.cancel)) { dialog, _ -> + dialog.dismiss() + } + val dialog = builder.create() + dialog.show() + } + + private fun serializeConversation(conversation: Conversation): HashMap { + val conversationMap = HashMap() + conversationMap["query"] = conversation.query ?: "" + conversationMap["response"] = conversation.response ?: "" + return conversationMap } - class ViewHolderChat(val rowChatHistoryBinding: RowChatHistoryBinding) : RecyclerView.ViewHolder(rowChatHistoryBinding.root) -} \ No newline at end of file + private fun getData(): Map> { + val expandableListDetail: MutableMap> = HashMap() + val community: MutableList = ArrayList() + community.add("community") + + val teams: MutableList = ArrayList() + teams.add("teams") + teams.add("enterprises") + + expandableListDetail["share with community"] = community + expandableListDetail["share with team/enterprise"] = teams + + return expandableListDetail + } + + class ViewHolderChat(val rowChatHistoryBinding: RowChatHistoryBinding) : RecyclerView.ViewHolder(rowChatHistoryBinding.root) + } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/news/ExpandableListAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/news/ExpandableListAdapter.kt new file mode 100644 index 0000000000..f0a81247b8 --- /dev/null +++ b/app/src/main/java/org/ole/planet/myplanet/ui/news/ExpandableListAdapter.kt @@ -0,0 +1,85 @@ +package org.ole.planet.myplanet.ui.news + +import android.content.Context +import android.graphics.Typeface +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseExpandableListAdapter +import android.widget.TextView +import org.ole.planet.myplanet.R + +class ExpandableListAdapter( + private val context: Context, + private val expandableTitleList: List, + private val expandableDetailList: HashMap> +) : BaseExpandableListAdapter() { + + override fun getChild(lstPosn: Int, expanded_ListPosition: Int): Any { + return expandableDetailList[expandableTitleList[lstPosn]]!![expanded_ListPosition] + } + + override fun getChildId(listPosition: Int, expanded_ListPosition: Int): Long { + return expanded_ListPosition.toLong() + } + + override fun getChildView( + lstPosn: Int, + expanded_ListPosition: Int, + isLastChild: Boolean, + convertView: View?, // Make convertView nullable + parent: ViewGroup + ): View { + var convertView = convertView + val expandedListText = getChild(lstPosn, expanded_ListPosition) as String + if (convertView == null) { + val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + convertView = layoutInflater.inflate(R.layout.expandable_list_item, null) + } + val expandedListTextView = convertView?.findViewById(R.id.expandedListItem) as TextView + expandedListTextView.text = expandedListText + return convertView + } + + override fun getChildrenCount(listPosition: Int): Int { + return expandableDetailList[expandableTitleList[listPosition]]!!.size + } + + override fun getGroup(listPosition: Int): Any { + return expandableTitleList[listPosition] + } + + override fun getGroupCount(): Int { + return expandableTitleList.size + } + + override fun getGroupId(listPosition: Int): Long { + return listPosition.toLong() + } + + override fun getGroupView( + listPosition: Int, + isExpanded: Boolean, + convertView: View?, // Make convertView nullable + parent: ViewGroup + ): View { + var convertView = convertView + val listTitle = getGroup(listPosition) as String + if (convertView == null) { + val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + convertView = layoutInflater.inflate(R.layout.expandable_list_group, null) + } + val listTitleTextView = convertView?.findViewById(R.id.listTitle) as TextView + listTitleTextView.setTypeface(null, Typeface.BOLD) + listTitleTextView.text = listTitle + return convertView + } + + override fun hasStableIds(): Boolean { + return false + } + + override fun isChildSelectable(listPosition: Int, expandedListPosition: Int): Boolean { + return true + } +} diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/news/GrandChildAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/news/GrandChildAdapter.kt new file mode 100644 index 0000000000..a985be19e9 --- /dev/null +++ b/app/src/main/java/org/ole/planet/myplanet/ui/news/GrandChildAdapter.kt @@ -0,0 +1,32 @@ +package org.ole.planet.myplanet.ui.news + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import org.ole.planet.myplanet.R +import org.ole.planet.myplanet.model.RealmMyTeam + +class GrandChildAdapter(private val items: List, private val onClick: (RealmMyTeam) -> Unit) : RecyclerView.Adapter() { + inner class GrandChildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val textView: TextView = itemView.findViewById(R.id.textView) + + fun bind(item: RealmMyTeam) { + textView.text = item.name + itemView.setOnClickListener { onClick(item) } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GrandChildViewHolder { + + val view = LayoutInflater.from(parent.context).inflate(R.layout.expandable_list_grand_child_item, parent, false) + return GrandChildViewHolder(view) + } + + override fun onBindViewHolder(holder: GrandChildViewHolder, position: Int) { + holder.bind(items[position]) + } + + override fun getItemCount() = items.size +} diff --git a/app/src/main/res/drawable/baseline_share_24.xml b/app/src/main/res/drawable/baseline_share_24.xml new file mode 100644 index 0000000000..74753b7aed --- /dev/null +++ b/app/src/main/res/drawable/baseline_share_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/custom_expandable.xml b/app/src/main/res/drawable/custom_expandable.xml new file mode 100644 index 0000000000..2aba3bfb1e --- /dev/null +++ b/app/src/main/res/drawable/custom_expandable.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/down_arrow.xml b/app/src/main/res/drawable/down_arrow.xml new file mode 100644 index 0000000000..9d454668cb --- /dev/null +++ b/app/src/main/res/drawable/down_arrow.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/up_arrow.xml b/app/src/main/res/drawable/up_arrow.xml new file mode 100644 index 0000000000..12cfa380ef --- /dev/null +++ b/app/src/main/res/drawable/up_arrow.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout/add_note_dialog.xml b/app/src/main/res/layout/add_note_dialog.xml new file mode 100644 index 0000000000..09dd7241b9 --- /dev/null +++ b/app/src/main/res/layout/add_note_dialog.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/layout/chat_share_dialog.xml b/app/src/main/res/layout/chat_share_dialog.xml new file mode 100644 index 0000000000..5405b9775d --- /dev/null +++ b/app/src/main/res/layout/chat_share_dialog.xml @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/app/src/main/res/layout/child_item.xml b/app/src/main/res/layout/child_item.xml new file mode 100644 index 0000000000..3b42c2e868 --- /dev/null +++ b/app/src/main/res/layout/child_item.xml @@ -0,0 +1,63 @@ + + + + + + + + +