First working sync (with hardcoded credentials and no concurrent modification checks)
This commit is contained in:
parent
106f721365
commit
6432045419
3
.gitignore
vendored
3
.gitignore
vendored
@ -103,3 +103,6 @@ app/release/output-metadata.json
|
|||||||
.idea/misc.xml
|
.idea/misc.xml
|
||||||
.idea/deploymentTargetSelector.xml
|
.idea/deploymentTargetSelector.xml
|
||||||
.idea/other.xml
|
.idea/other.xml
|
||||||
|
|
||||||
|
# Other
|
||||||
|
app/src/main/java/it/danieleverducci/lunatracker/TemporaryHardcodedCredentials.kt
|
||||||
|
3
.idea/.gitignore
vendored
3
.idea/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<bytecodeTargetLevel target="21" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,57 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
@ -51,6 +51,8 @@ dependencies {
|
|||||||
implementation(libs.androidx.material3)
|
implementation(libs.androidx.material3)
|
||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
implementation(libs.androidx.recyclerview)
|
implementation(libs.androidx.recyclerview)
|
||||||
|
implementation("com.github.thegrizzlylabs:sardine-android:v0.9")
|
||||||
|
implementation(libs.material)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
package it.danieleverducci.lunatracker
|
package it.danieleverducci.lunatracker
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.preference.PreferenceManager
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.NumberPicker
|
import android.widget.NumberPicker
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.edit
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
import it.danieleverducci.lunatracker.adapters.LunaEventRecyclerAdapter
|
import it.danieleverducci.lunatracker.adapters.LunaEventRecyclerAdapter
|
||||||
import it.danieleverducci.lunatracker.entities.Logbook
|
import it.danieleverducci.lunatracker.entities.Logbook
|
||||||
import it.danieleverducci.lunatracker.entities.LunaEvent
|
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||||
import it.danieleverducci.lunatracker.entities.LunaEventType
|
import it.danieleverducci.lunatracker.entities.LunaEventType
|
||||||
|
import it.danieleverducci.lunatracker.repository.LogbookLoadedListener
|
||||||
|
import it.danieleverducci.lunatracker.repository.LogbookRepository
|
||||||
|
import it.danieleverducci.lunatracker.repository.LogbookSavedListener
|
||||||
|
import it.danieleverducci.lunatracker.repository.WebDAVLogbookRepository
|
||||||
import kotlinx.coroutines.Runnable
|
import kotlinx.coroutines.Runnable
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
@ -28,28 +31,30 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
lateinit var logbook: Logbook
|
lateinit var logbook: Logbook
|
||||||
lateinit var adapter: LunaEventRecyclerAdapter
|
lateinit var adapter: LunaEventRecyclerAdapter
|
||||||
|
lateinit var progressIndicator: LinearProgressIndicator
|
||||||
lateinit var recyclerView: RecyclerView
|
lateinit var recyclerView: RecyclerView
|
||||||
lateinit var handler: Handler
|
lateinit var handler: Handler
|
||||||
val updateListRunnable: Runnable = Runnable {
|
val updateListRunnable: Runnable = Runnable {
|
||||||
adapter.notifyDataSetChanged()
|
loadLogbook()
|
||||||
handler.postDelayed(updateListRunnable, 1000*30)
|
handler.postDelayed(updateListRunnable, 1000*60)
|
||||||
}
|
}
|
||||||
|
val logbookRepo: LogbookRepository = WebDAVLogbookRepository( // TODO: support also FileLogbookRepository
|
||||||
|
TemporaryHardcodedCredentials.URL,
|
||||||
|
TemporaryHardcodedCredentials.USERNAME,
|
||||||
|
TemporaryHardcodedCredentials.PASSWORD
|
||||||
|
)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
handler = Handler(mainLooper)
|
handler = Handler(mainLooper)
|
||||||
|
adapter = LunaEventRecyclerAdapter(this)
|
||||||
// Load data
|
|
||||||
logbook = Logbook.load(this)
|
|
||||||
|
|
||||||
// Show view
|
// Show view
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
// Show logbook
|
progressIndicator = findViewById<LinearProgressIndicator>(R.id.progress_indicator)
|
||||||
recyclerView = findViewById<RecyclerView>(R.id.list_events)
|
recyclerView = findViewById<RecyclerView>(R.id.list_events)
|
||||||
recyclerView.setLayoutManager(LinearLayoutManager(this))
|
recyclerView.setLayoutManager(LinearLayoutManager(applicationContext))
|
||||||
adapter = LunaEventRecyclerAdapter(this)
|
|
||||||
adapter.items.addAll(logbook.logs)
|
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
|
|
||||||
// Set listeners
|
// Set listeners
|
||||||
@ -82,11 +87,18 @@ class MainActivity : AppCompatActivity() {
|
|||||||
) }
|
) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showLogbook() {
|
||||||
|
// Show logbook
|
||||||
|
adapter.items.clear()
|
||||||
|
adapter.items.addAll(logbook.logs)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
|
||||||
// Update list dates
|
// Update list dates
|
||||||
adapter.notifyDataSetChanged()
|
loadLogbook()
|
||||||
handler.postDelayed(updateListRunnable, 1000*30)
|
handler.postDelayed(updateListRunnable, 1000*30)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,13 +150,52 @@ class MainActivity : AppCompatActivity() {
|
|||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loadLogbook() {
|
||||||
|
// Load data
|
||||||
|
progressIndicator.visibility = View.VISIBLE
|
||||||
|
logbookRepo.loadLogbook(this, object: LogbookLoadedListener{
|
||||||
|
override fun onLogbookLoaded(lb: Logbook) {
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
logbook = lb
|
||||||
|
showLogbook()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(error: String) {
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
Log.e(TAG, "Unable to load logbook. Create a new one.")
|
||||||
|
logbook = Logbook()
|
||||||
|
showLogbook()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fun logEvent(event: LunaEvent) {
|
fun logEvent(event: LunaEvent) {
|
||||||
adapter.items.add(0, event)
|
adapter.items.add(0, event)
|
||||||
adapter.notifyItemInserted(0)
|
adapter.notifyItemInserted(0)
|
||||||
recyclerView.smoothScrollToPosition(0)
|
recyclerView.smoothScrollToPosition(0)
|
||||||
|
|
||||||
|
progressIndicator.visibility = View.VISIBLE
|
||||||
logbook.logs.add(0, event)
|
logbook.logs.add(0, event)
|
||||||
logbook.save(this)
|
logbookRepo.saveLogbook(this, logbook, object: LogbookSavedListener{
|
||||||
|
override fun onLogbookSaved() {
|
||||||
|
Log.d(TAG, "Logbook saved")
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(error: String) {
|
||||||
|
Log.e(TAG, "ERROR: Logbook was NOT saved!")
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
Toast.makeText(this, R.string.toast_event_added, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.toast_event_added, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,5 @@
|
|||||||
package it.danieleverducci.lunatracker.entities
|
package it.danieleverducci.lunatracker.entities
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.Log
|
|
||||||
import org.json.JSONArray
|
|
||||||
import java.io.File
|
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.FileNotFoundException
|
|
||||||
|
|
||||||
class Logbook {
|
class Logbook {
|
||||||
companion object {
|
|
||||||
val TAG = "Logbook"
|
|
||||||
|
|
||||||
fun load(context: Context): Logbook {
|
|
||||||
val logbook = Logbook()
|
|
||||||
val file = File(context.getFilesDir(), "data.json")
|
|
||||||
try {
|
|
||||||
val json = FileInputStream(file).bufferedReader().use { it.readText() }
|
|
||||||
val ja = JSONArray(json)
|
|
||||||
for (i in 0 until ja.length()) {
|
|
||||||
val jo = ja.getJSONObject(i)
|
|
||||||
val evt = LunaEvent.fromJson(jo)
|
|
||||||
logbook.logs.add(evt)
|
|
||||||
}
|
|
||||||
} catch (e: FileNotFoundException) {
|
|
||||||
Log.d(TAG, "No logbook file found")
|
|
||||||
}
|
|
||||||
return logbook
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val logs = ArrayList<LunaEvent>()
|
val logs = ArrayList<LunaEvent>()
|
||||||
|
|
||||||
fun save(context: Context) {
|
|
||||||
val file = File(context.getFilesDir(), "data.json")
|
|
||||||
val ja = JSONArray()
|
|
||||||
for (l in logs) {
|
|
||||||
ja.put(l.toJson())
|
|
||||||
}
|
|
||||||
file.writeText(ja.toString())
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package it.danieleverducci.lunatracker.repository
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import it.danieleverducci.lunatracker.entities.Logbook
|
||||||
|
import android.util.Log
|
||||||
|
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||||
|
import org.json.JSONArray
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
|
||||||
|
class FileLogbookRepository: LogbookRepository {
|
||||||
|
companion object {
|
||||||
|
val TAG = "FileLogbookRepository"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadLogbook(context: Context, listener: LogbookLoadedListener) {
|
||||||
|
val logbook = Logbook()
|
||||||
|
val file = File(context.getFilesDir(), "data.json")
|
||||||
|
try {
|
||||||
|
val json = FileInputStream(file).bufferedReader().use { it.readText() }
|
||||||
|
val ja = JSONArray(json)
|
||||||
|
for (i in 0 until ja.length()) {
|
||||||
|
val jo = ja.getJSONObject(i)
|
||||||
|
val evt = LunaEvent.fromJson(jo)
|
||||||
|
logbook.logs.add(evt)
|
||||||
|
}
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
Log.d(TAG, "No logbook file found")
|
||||||
|
listener.onError(e.toString())
|
||||||
|
}
|
||||||
|
listener.onLogbookLoaded(logbook)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveLogbook(
|
||||||
|
context: Context,
|
||||||
|
logbook: Logbook,
|
||||||
|
listener: LogbookSavedListener
|
||||||
|
) {
|
||||||
|
val file = File(context.getFilesDir(), "data.json")
|
||||||
|
val ja = JSONArray()
|
||||||
|
for (l in logbook.logs) {
|
||||||
|
ja.put(l.toJson())
|
||||||
|
}
|
||||||
|
file.writeText(ja.toString())
|
||||||
|
listener.onLogbookSaved()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package it.danieleverducci.lunatracker.repository
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import it.danieleverducci.lunatracker.entities.Logbook
|
||||||
|
|
||||||
|
interface LogbookRepository {
|
||||||
|
fun loadLogbook(context: Context, listener: LogbookLoadedListener)
|
||||||
|
fun saveLogbook(context: Context, logbook: Logbook, listener: LogbookSavedListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LogbookLoadedListener {
|
||||||
|
fun onLogbookLoaded(logbook: Logbook)
|
||||||
|
fun onError(error: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LogbookSavedListener {
|
||||||
|
fun onLogbookSaved()
|
||||||
|
fun onError(error: String)
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package it.danieleverducci.lunatracker.repository
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.thegrizzlylabs.sardineandroid.impl.OkHttpSardine
|
||||||
|
import com.thegrizzlylabs.sardineandroid.impl.SardineException
|
||||||
|
import it.danieleverducci.lunatracker.TemporaryHardcodedCredentials
|
||||||
|
import it.danieleverducci.lunatracker.entities.Logbook
|
||||||
|
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||||
|
import kotlinx.coroutines.Runnable
|
||||||
|
import org.json.JSONArray
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import kotlin.io.bufferedReader
|
||||||
|
|
||||||
|
class WebDAVLogbookRepository(val webDavURL: String, val username: String, val password: String): LogbookRepository {
|
||||||
|
companion object {
|
||||||
|
val TAG = "LogbookRepository"
|
||||||
|
val FILE_NAME = "lunatracker_logbook.json"
|
||||||
|
}
|
||||||
|
val sardine: OkHttpSardine = OkHttpSardine()
|
||||||
|
|
||||||
|
init {
|
||||||
|
sardine.setCredentials(
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadLogbook(context: Context, listener: LogbookLoadedListener) {
|
||||||
|
Thread(Runnable {
|
||||||
|
try {
|
||||||
|
val inputStream = sardine.get("$webDavURL/$FILE_NAME")
|
||||||
|
val json = inputStream.bufferedReader().use(BufferedReader::readText)
|
||||||
|
val ja = JSONArray(json)
|
||||||
|
val logbook = Logbook()
|
||||||
|
for (i in 0 until ja.length()) {
|
||||||
|
val jo = ja.getJSONObject(i)
|
||||||
|
val evt = LunaEvent.fromJson(jo)
|
||||||
|
logbook.logs.add(evt)
|
||||||
|
}
|
||||||
|
listener.onLogbookLoaded(logbook)
|
||||||
|
} catch (e: SardineException) {
|
||||||
|
listener.onError(e.toString())
|
||||||
|
}
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveLogbook(context: Context, logbook: Logbook, listener: LogbookSavedListener) {
|
||||||
|
Thread(Runnable {
|
||||||
|
// Lock logbook on WebDAV to avoid concurrent changes
|
||||||
|
//sardine.lock(getUrl())
|
||||||
|
// Reload logbook from WebDAV
|
||||||
|
// Merge logbooks (based on time)
|
||||||
|
// Write logbook
|
||||||
|
// Unlock logbook on WebDAV
|
||||||
|
//sardine.unlock(getUrl())
|
||||||
|
|
||||||
|
val ja = JSONArray()
|
||||||
|
for (l in logbook.logs) {
|
||||||
|
ja.put(l.toJson())
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sardine.put(getUrl(), ja.toString().toByteArray())
|
||||||
|
listener.onLogbookSaved()
|
||||||
|
} catch (e: SardineException) {
|
||||||
|
listener.onError(e.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUrl(): String {
|
||||||
|
return "${TemporaryHardcodedCredentials.URL}/$FILE_NAME"
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<LinearLayout
|
<LinearLayout 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:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingTop="30dp"
|
android:paddingTop="30dp"
|
||||||
android:paddingLeft="15dp"
|
android:paddingLeft="15dp"
|
||||||
@ -116,11 +116,21 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
|
android:id="@+id/progress_indicator"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:indeterminate="true"
|
||||||
|
app:indicatorColor="@color/accent"
|
||||||
|
android:visibility="invisible"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Diario di bordo"
|
android:text="Diario di bordo"
|
||||||
android:layout_marginTop="30dp"/>
|
android:textColor="@color/accent"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/list_events"
|
android:id="@+id/list_events"
|
||||||
|
@ -10,6 +10,7 @@ activityCompose = "1.8.0"
|
|||||||
composeBom = "2024.04.01"
|
composeBom = "2024.04.01"
|
||||||
appcompat = "1.7.0"
|
appcompat = "1.7.0"
|
||||||
recyclerview = "1.3.2"
|
recyclerview = "1.3.2"
|
||||||
|
material = "1.12.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
@ -28,6 +29,7 @@ androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-man
|
|||||||
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
|
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||||
|
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
@ -16,6 +16,7 @@ dependencyResolutionManagement {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven(url = "https://jitpack.io")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user