kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
Merge remote-tracking branch 'root/master' into dev
commit
0e6a82255e
|
@ -806,7 +806,8 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
// Init our messages table with the service's record of past text messages (ignore all other message types)
|
||||
val msgs =
|
||||
service.oldMessages.filter { p -> p.dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE }
|
||||
debug("Service provided ${msgs.size} messages")
|
||||
debug("Service provided ${msgs.size} messages and myNodeNum ${service.myNodeInfo?.myNodeNum}")
|
||||
model.myNodeInfo.value = service.myNodeInfo
|
||||
model.messagesState.setMessages(msgs)
|
||||
val connectionState =
|
||||
MeshService.ConnectionState.valueOf(service.connectionState())
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.view.inputmethod.EditorInfo
|
|||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
@ -15,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.DataPacket
|
||||
import com.geeksville.mesh.MessageStatus
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.databinding.AdapterMessageLayoutBinding
|
||||
import com.geeksville.mesh.databinding.MessagesFragmentBinding
|
||||
|
@ -22,6 +24,7 @@ import com.geeksville.mesh.model.UIViewModel
|
|||
import com.geeksville.mesh.service.MeshService
|
||||
import com.google.android.material.chip.Chip
|
||||
import java.text.DateFormat
|
||||
import java.text.ParseException
|
||||
import java.util.*
|
||||
|
||||
// Allows usage like email.on(EditorInfo.IME_ACTION_NEXT, { confirm() })
|
||||
|
@ -39,20 +42,35 @@ fun EditText.on(actionId: Int, func: () -> Unit) {
|
|||
class MessagesFragment : ScreenFragment("Messages"), Logging {
|
||||
|
||||
private var _binding: MessagesFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val model: UIViewModel by activityViewModels()
|
||||
|
||||
private val dateTimeFormat: DateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)
|
||||
private val dateTimeFormat: DateFormat =
|
||||
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT)
|
||||
private val timeFormat: DateFormat =
|
||||
DateFormat.getTimeInstance(DateFormat.SHORT)
|
||||
|
||||
private fun getShortDateTime(time : Date): String {
|
||||
// return time if within 24 hours, otherwise date/time
|
||||
val one_day = 60*60*24*100L
|
||||
if (System.currentTimeMillis() - time.time > one_day) {
|
||||
return dateTimeFormat.format(time)
|
||||
} else return timeFormat.format(time)
|
||||
}
|
||||
|
||||
|
||||
// Provide a direct reference to each of the views within a data item
|
||||
// Used to cache the views within the item layout for fast access
|
||||
class ViewHolder(itemView: AdapterMessageLayoutBinding) : RecyclerView.ViewHolder(itemView.root) {
|
||||
class ViewHolder(itemView: AdapterMessageLayoutBinding) :
|
||||
RecyclerView.ViewHolder(itemView.root) {
|
||||
val username: Chip = itemView.username
|
||||
val messageText: TextView = itemView.messageText
|
||||
val messageTime: TextView = itemView.messageTime
|
||||
val messageStatusIcon: ImageView = itemView.messageStatusIcon
|
||||
val card: CardView = itemView.Card
|
||||
}
|
||||
|
||||
private val messagesAdapter = object : RecyclerView.Adapter<ViewHolder>() {
|
||||
|
@ -122,14 +140,32 @@ class MessagesFragment : ScreenFragment("Messages"), Logging {
|
|||
*/
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val msg = messages[position]
|
||||
|
||||
val nodes = model.nodeDB.nodes.value!!
|
||||
|
||||
// If we can't find the sender, just use the ID
|
||||
val node = nodes.get(msg.from)
|
||||
val user = node?.user
|
||||
holder.username.text = user?.shortName ?: msg.from
|
||||
// Determine if this is my message (originated on this device).
|
||||
val isMe = model.myNodeInfo.value?.myNodeNum == node?.num
|
||||
|
||||
// Set cardview offset and color.
|
||||
val marginParams = holder.card.layoutParams as ViewGroup.MarginLayoutParams
|
||||
val messageOffset = resources.getDimensionPixelOffset(R.dimen.message_offset)
|
||||
if (isMe) {
|
||||
marginParams.leftMargin = messageOffset
|
||||
marginParams.rightMargin = 0
|
||||
holder.card.setCardBackgroundColor(resources.getColor(R.color.colorMyMsg))
|
||||
} else {
|
||||
marginParams.rightMargin = messageOffset
|
||||
marginParams.leftMargin = 0
|
||||
holder.card.setCardBackgroundColor(resources.getColor(R.color.colorMsg))
|
||||
}
|
||||
// Hide the username chip for my messages
|
||||
if (isMe) {
|
||||
holder.username.visibility = View.GONE
|
||||
} else {
|
||||
holder.username.visibility = View.VISIBLE
|
||||
// If we can't find the sender, just use the ID
|
||||
val user = node?.user
|
||||
holder.username.text = user?.shortName ?: msg.from
|
||||
}
|
||||
if (msg.errorMessage != null) {
|
||||
// FIXME, set the style to show a red error message
|
||||
holder.messageText.text = msg.errorMessage
|
||||
|
@ -137,7 +173,7 @@ class MessagesFragment : ScreenFragment("Messages"), Logging {
|
|||
holder.messageText.text = msg.text
|
||||
}
|
||||
|
||||
holder.messageTime.text = dateTimeFormat.format(Date(msg.time))
|
||||
holder.messageTime.text = getShortDateTime(Date(msg.time))
|
||||
|
||||
val icon = when (msg.status) {
|
||||
MessageStatus.QUEUED -> R.drawable.ic_twotone_cloud_upload_24
|
||||
|
@ -150,6 +186,7 @@ class MessagesFragment : ScreenFragment("Messages"), Logging {
|
|||
if (icon != null) {
|
||||
holder.messageStatusIcon.setImageResource(icon)
|
||||
holder.messageStatusIcon.visibility = View.VISIBLE
|
||||
|
||||
} else
|
||||
holder.messageStatusIcon.visibility = View.INVISIBLE
|
||||
}
|
||||
|
|
|
@ -1,61 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:clipToPadding="false"
|
||||
android:contentDescription="Message delivery status"
|
||||
android:elevation="2dp">
|
||||
android:contentDescription="Message delivery status">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/Card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/message_offset"
|
||||
app:cardBackgroundColor="@color/colorMsg"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="2dp"
|
||||
app:cardUseCompatPadding="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/some_username"
|
||||
app:chipIcon="@drawable/ic_twotone_person_24"
|
||||
app:layout_constraintEnd_toEndOf="@+id/messageTime"
|
||||
app:layout_constraintStart_toStartOf="@+id/messageTime"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:autoLink="all"
|
||||
android:text="@string/sample_message"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/username"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="@string/some_username"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="3 min"
|
||||
app:layout_constraintStart_toStartOf="@+id/username"
|
||||
app:layout_constraintTop_toBottomOf="@+id/username" />
|
||||
<TextView
|
||||
android:id="@+id/messageText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:autoLink="all"
|
||||
android:text="@string/sample_message"
|
||||
android:textIsSelectable="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/username"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageStatusIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/messageText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/cloud_on" />
|
||||
<ImageView
|
||||
android:id="@+id/messageStatusIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/messageText"
|
||||
app:srcCompat="@drawable/cloud_on" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<TextView
|
||||
android:id="@+id/messageTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="3 minutes ago"
|
||||
app:layout_constraintEnd_toStartOf="@id/messageStatusIcon"
|
||||
app:layout_constraintTop_toBottomOf="@id/messageText" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
|
@ -3,4 +3,6 @@
|
|||
<color name="colorPrimary">#3700B3</color>
|
||||
<color name="colorPrimaryDark">#3700B3</color>
|
||||
<color name="colorAccent">#D81B60</color>
|
||||
<color name="colorMsg">#07000000</color>
|
||||
<color name="colorMyMsg">#403700B3</color>
|
||||
</resources>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<resources>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
<dimen name="message_offset">64dp</dimen>
|
||||
</resources>
|
||||
|
|
Ładowanie…
Reference in New Issue