Show Logs in Settings on Android

This commit is contained in:
Florian Märkl 2019-11-01 11:27:28 +01:00
commit 588548cbb3
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
7 changed files with 109 additions and 18 deletions

View file

@ -24,11 +24,11 @@ import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
private val dateFormat = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SSSSSS", Locale.US) private val dateFormat = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SSS", Locale.US)
private val filePrefix = "chiaki_session_" private const val filePrefix = "chiaki_session_"
private val filePostfix = ".log" private const val filePostfix = ".log"
private val fileRegex = Regex("$filePrefix(.*)$filePostfix") private val fileRegex = Regex("$filePrefix(.*)$filePostfix")
private val keepLogFilesCount = 5 private const val keepLogFilesCount = 5
class LogFile private constructor(val logManager: LogManager, val filename: String) class LogFile private constructor(val logManager: LogManager, val filename: String)
{ {

View file

@ -21,15 +21,21 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.metallic.chiaki.R import com.metallic.chiaki.R
import com.metallic.chiaki.common.RegisteredHost import com.metallic.chiaki.common.LogFile
import com.metallic.chiaki.common.ext.inflate import com.metallic.chiaki.common.ext.inflate
import kotlinx.android.synthetic.main.item_registered_host.view.* import kotlinx.android.synthetic.main.item_log_file.view.*
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
class SettingsLogsAdapter: RecyclerView.Adapter<SettingsLogsAdapter.ViewHolder>() class SettingsLogsAdapter: RecyclerView.Adapter<SettingsLogsAdapter.ViewHolder>()
{ {
val dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
val timeFormat = SimpleDateFormat("HH:mm:ss:SSS", Locale.getDefault())
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
var logFiles: List<String> = listOf() var logFiles: List<LogFile> = listOf()
set(value) set(value)
{ {
field = value field = value
@ -44,6 +50,7 @@ class SettingsLogsAdapter: RecyclerView.Adapter<SettingsLogsAdapter.ViewHolder>(
{ {
val view = holder.itemView val view = holder.itemView
val logFile = logFiles[position] val logFile = logFiles[position]
// TODO view.nameTextView.text = "${dateFormat.format(logFile.date)} ${timeFormat.format(logFile.date)}"
view.summaryTextView.text = logFile.filename
} }
} }

View file

@ -23,9 +23,13 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDialogFragment import androidx.appcompat.app.AppCompatDialogFragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.metallic.chiaki.R import com.metallic.chiaki.R
import com.metallic.chiaki.common.LogManager
import com.metallic.chiaki.common.ext.viewModelFactory import com.metallic.chiaki.common.ext.viewModelFactory
import kotlinx.android.synthetic.main.fragment_settings_logs.* import kotlinx.android.synthetic.main.fragment_settings_logs.*
@ -38,13 +42,30 @@ class SettingsLogsFragment: AppCompatDialogFragment(), TitleFragment
override fun onViewCreated(view: View, savedInstanceState: Bundle?) override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{ {
val context = context!!
viewModel = ViewModelProviders viewModel = ViewModelProviders
.of(this, viewModelFactory { SettingsLogsViewModel() }) .of(this, viewModelFactory { SettingsLogsViewModel(LogManager(context)) })
.get(SettingsLogsViewModel::class.java) .get(SettingsLogsViewModel::class.java)
val adapter = SettingsLogsAdapter() val adapter = SettingsLogsAdapter()
logsRecyclerView.layoutManager = LinearLayoutManager(context) logsRecyclerView.layoutManager = LinearLayoutManager(context)
logsRecyclerView.adapter = adapter logsRecyclerView.adapter = adapter
viewModel.sessionLogs.observe(this, Observer {
adapter.logFiles = it
emptyInfoGroup.visibility = if(it.isEmpty()) View.VISIBLE else View.GONE
})
val itemTouchSwipeCallback = object : ItemTouchSwipeCallback(context)
{
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int)
{
val pos = viewHolder.adapterPosition
val file = viewModel.sessionLogs.value?.getOrNull(pos) ?: return
viewModel.deleteLog(file)
}
}
ItemTouchHelper(itemTouchSwipeCallback).attachToRecyclerView(logsRecyclerView)
} }
override fun getTitle(resources: Resources): String = resources.getString(R.string.preferences_logs_title) override fun getTitle(resources: Resources): String = resources.getString(R.string.preferences_logs_title)

View file

@ -17,14 +17,31 @@
package com.metallic.chiaki.settings package com.metallic.chiaki.settings
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.metallic.chiaki.common.AppDatabase import com.metallic.chiaki.common.AppDatabase
import com.metallic.chiaki.common.LogFile
import com.metallic.chiaki.common.LogManager
import com.metallic.chiaki.common.RegisteredHost import com.metallic.chiaki.common.RegisteredHost
import com.metallic.chiaki.common.ext.toLiveData import com.metallic.chiaki.common.ext.toLiveData
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo import io.reactivex.rxkotlin.addTo
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
class SettingsLogsViewModel: ViewModel() class SettingsLogsViewModel(val logManager: LogManager): ViewModel()
{ {
private val _sessionLogs = MutableLiveData<List<LogFile>>(logManager.files)
val sessionLogs: LiveData<List<LogFile>> get() = _sessionLogs
private fun updateLogs()
{
_sessionLogs.value = logManager.files
}
fun deleteLog(file: LogFile)
{
file.file.delete()
updateLogs()
}
} }

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootLayout"> android:id="@+id/rootLayout">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
@ -11,4 +11,34 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<ImageView
android:id="@+id/emptyInfoImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_log"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/emptyInfoTextView"
app:layout_constraintVertical_chainStyle="packed"
android:alpha="0.5"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/emptyInfoTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="sans-serif-condensed"
android:text="@string/session_logs_empty_info"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/emptyInfoImageView" />
<androidx.constraintlayout.widget.Group
android:id="@+id/emptyInfoGroup"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="emptyInfoImageView,emptyInfoTextView"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -25,7 +25,7 @@
<TextView <TextView
android:id="@+id/nameTextView" android:id="@+id/nameTextView"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:singleLine="true" android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
@ -34,13 +34,15 @@
android:fadingEdge="horizontal" android:fadingEdge="horizontal"
app:layout_constraintStart_toEndOf="@id/iconImageView" app:layout_constraintStart_toEndOf="@id/iconImageView"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
tools:text="Name" /> tools:text="Name"
app:layout_constraintEnd_toStartOf="@id/shareButton"
app:layout_constraintBottom_toTopOf="@id/summaryTextView"
app:layout_constraintVertical_chainStyle="packed"/>
<!--<TextView <TextView
android:id="@+id/summaryTextView" android:id="@+id/summaryTextView"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@android:id/title" android:layout_below="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
@ -49,6 +51,19 @@
app:layout_constraintStart_toStartOf="@id/nameTextView" app:layout_constraintStart_toStartOf="@id/nameTextView"
app:layout_constraintTop_toBottomOf="@id/nameTextView" app:layout_constraintTop_toBottomOf="@id/nameTextView"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
tools:text="Summary"/>--> tools:text="Summary"
app:layout_constraintEnd_toEndOf="@id/nameTextView" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shareButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_share"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:tint="?android:attr/textColorPrimary"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:padding="16dp"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -74,6 +74,7 @@
<string name="action_keep">Keep</string> <string name="action_keep">Keep</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="session_logs_empty_info">No Session Logs recorded.</string>
<!-- Don't localize these --> <!-- Don't localize these -->
<string name="preferences_discovery_enabled_key">discovery_enabled</string> <string name="preferences_discovery_enabled_key">discovery_enabled</string>