Compare commits
2
Commits
f2dac546d0
...
0224e8f395
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0224e8f395 | ||
|
|
ee1079a079 |
No files matched your search
@@ -10,7 +10,7 @@ The gear icon opens **Car**. A new install already has the server address filled
|
||||
|
||||
`http://sync.sleepingliongames.com:27017`
|
||||
|
||||
**Sync on its own** sends a save right away, checks about every 30 seconds while the app is open, and about every 15 minutes while it is closed. **Sync now** sends every car on the phone.
|
||||
**Sync on its own** sends a save right away and checks about every 30 seconds while the app is open. It stays quiet while the app is closed. **Sync now** sends every car on the phone.
|
||||
|
||||
Each car has its own token, shown on the **Car** screen. **Share token** sends that string to another phone. On the other phone, paste it under **Add a car from a token**. That phone then syncs that car. A different car gets a different token.
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ dependencies {
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.androidx.room.ktx)
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
implementation(libs.androidx.work)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
testImplementation(libs.junit)
|
||||
|
||||
@@ -18,8 +18,7 @@ open class RacingApp : Application() {
|
||||
val dao = AppDatabase.create(this).raceDao()
|
||||
val preferences = SyncPreferences(this)
|
||||
runBlocking(Dispatchers.IO) { ensureCars(dao, preferences) }
|
||||
val sync = PitSync(this, dao, preferences)
|
||||
val sync = PitSync(dao, preferences)
|
||||
repository = Repository(dao, sync, preferences)
|
||||
sync.schedule()
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,10 @@
|
||||
package com.racingapp.pitlog.data
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.NetworkType
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.time.LocalTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@@ -23,10 +16,7 @@ import org.json.JSONObject
|
||||
|
||||
class SyncException(message: String) : Exception(message)
|
||||
|
||||
private const val WORK_NAME = "pitlog-sync"
|
||||
|
||||
class PitSync(
|
||||
private val appContext: Context,
|
||||
private val dao: RaceDao,
|
||||
private val preferences: SyncPreferences,
|
||||
) {
|
||||
@@ -39,30 +29,10 @@ class PitSync(
|
||||
|
||||
fun saveAddress(address: String) {
|
||||
preferences.address = address.trim().trimEnd('/')
|
||||
schedule()
|
||||
}
|
||||
|
||||
fun setAutomatic(enabled: Boolean) {
|
||||
preferences.automatic = enabled
|
||||
schedule()
|
||||
}
|
||||
|
||||
fun schedule() {
|
||||
try {
|
||||
val manager = WorkManager.getInstance(appContext)
|
||||
if (!preferences.automatic || preferences.address.isBlank()) {
|
||||
manager.cancelUniqueWork(WORK_NAME)
|
||||
return
|
||||
}
|
||||
val request = PeriodicWorkRequestBuilder<SyncWorker>(15, TimeUnit.MINUTES)
|
||||
.setConstraints(
|
||||
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
|
||||
)
|
||||
.build()
|
||||
manager.enqueueUniquePeriodicWork(WORK_NAME, ExistingPeriodicWorkPolicy.UPDATE, request)
|
||||
} catch (_: Exception) {
|
||||
// Unit tests do not start WorkManager.
|
||||
}
|
||||
}
|
||||
|
||||
fun launchAutomatic() {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.racingapp.pitlog.data
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.racingapp.pitlog.RacingApp
|
||||
|
||||
class SyncWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters,
|
||||
) : CoroutineWorker(context, params) {
|
||||
override suspend fun doWork(): Result {
|
||||
val app = applicationContext as? RacingApp ?: return Result.success()
|
||||
app.repository.syncAutomatic()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
@@ -286,7 +286,7 @@ fun SettingsScreen(onBack: () -> Unit) {
|
||||
}
|
||||
SectionLabel("Server")
|
||||
Text(
|
||||
"This is the Pelican address. Every car on this phone uses it. Sync on its own sends each save right away, checks every half minute while the app is open, and about every 15 minutes while it is closed.",
|
||||
"This is the Pelican address. Every car on this phone uses it. Sync on its own sends each save right away and checks every half minute while the app is open.",
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Row(
|
||||
|
||||
@@ -9,7 +9,6 @@ lifecycle = "2.11.0"
|
||||
activity = "1.12.4"
|
||||
core = "1.19.1"
|
||||
coroutines = "1.10.1"
|
||||
work = "2.10.1"
|
||||
junit = "4.13.2"
|
||||
robolectric = "4.16"
|
||||
androidxTestCore = "1.6.1"
|
||||
@@ -32,7 +31,6 @@ androidx-room-runtime = { group = "androidx.room", name = "room-runtime", versio
|
||||
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
|
||||
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
||||
androidx-work = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||
androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" }
|
||||
|
||||
@@ -355,6 +355,22 @@ def sync_body(payload, db=None):
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
protocol_version = "HTTP/1.1"
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
super().handle()
|
||||
except (ConnectionError, TimeoutError):
|
||||
return
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
try:
|
||||
self.close_connection = True
|
||||
self.send_response_only(code)
|
||||
self.send_header("Content-Length", "0")
|
||||
self.send_header("Connection", "close")
|
||||
self.end_headers()
|
||||
except (ConnectionError, TimeoutError):
|
||||
self.close_connection = True
|
||||
|
||||
def log_message(self, fmt, *args):
|
||||
sys.stdout.write("%s - %s\n" % (self.address_string(), fmt % args))
|
||||
|
||||
|
||||
Reference in new issue
Block a user