AboutScreen: add button to copy logs to clipboard
This commit is contained in:
committed by
pynicolas
parent
f4aad46cb6
commit
3f10a1cd55
@@ -28,6 +28,7 @@ import org.fairscan.app.data.recentDocumentsDataStore
|
|||||||
import org.fairscan.app.domain.ImageSegmentationService
|
import org.fairscan.app.domain.ImageSegmentationService
|
||||||
import org.fairscan.app.platform.AndroidPdfWriter
|
import org.fairscan.app.platform.AndroidPdfWriter
|
||||||
import org.fairscan.app.platform.OpenCvTransformations
|
import org.fairscan.app.platform.OpenCvTransformations
|
||||||
|
import org.fairscan.app.ui.screens.about.AboutViewModel
|
||||||
import org.fairscan.app.ui.screens.camera.CameraViewModel
|
import org.fairscan.app.ui.screens.camera.CameraViewModel
|
||||||
import org.fairscan.app.ui.screens.export.ExportViewModel
|
import org.fairscan.app.ui.screens.export.ExportViewModel
|
||||||
import org.fairscan.app.ui.screens.home.HomeViewModel
|
import org.fairscan.app.ui.screens.home.HomeViewModel
|
||||||
@@ -53,7 +54,8 @@ class AppContainer(context: Context) {
|
|||||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
|
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
|
||||||
AndroidPdfWriter()
|
AndroidPdfWriter()
|
||||||
)
|
)
|
||||||
val logger = FileLogger(LogRepository(File(context.filesDir, "logs.txt")))
|
val logRepository = LogRepository(File(context.filesDir, "logs.txt"))
|
||||||
|
val logger = FileLogger(logRepository)
|
||||||
val imageSegmentationService = ImageSegmentationService(context, logger)
|
val imageSegmentationService = ImageSegmentationService(context, logger)
|
||||||
val recentDocumentsDataStore = context.recentDocumentsDataStore
|
val recentDocumentsDataStore = context.recentDocumentsDataStore
|
||||||
|
|
||||||
@@ -70,4 +72,5 @@ class AppContainer(context: Context) {
|
|||||||
val homeViewModelFactory = viewModelFactory { HomeViewModel(it) }
|
val homeViewModelFactory = viewModelFactory { HomeViewModel(it) }
|
||||||
val cameraViewModelFactory = viewModelFactory { CameraViewModel(it) }
|
val cameraViewModelFactory = viewModelFactory { CameraViewModel(it) }
|
||||||
val exportViewModelFactory = viewModelFactory { ExportViewModel(it) }
|
val exportViewModelFactory = viewModelFactory { ExportViewModel(it) }
|
||||||
|
val aboutViewModelFactory = viewModelFactory { AboutViewModel(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package org.fairscan.app
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||||
@@ -34,7 +35,10 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.platform.LocalClipboard
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.toClipEntry
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.core.content.ContextCompat.checkSelfPermission
|
import androidx.core.content.ContextCompat.checkSelfPermission
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.net.toFile
|
import androidx.core.net.toFile
|
||||||
@@ -47,9 +51,11 @@ import org.fairscan.app.data.GeneratedPdf
|
|||||||
import org.fairscan.app.ui.Navigation
|
import org.fairscan.app.ui.Navigation
|
||||||
import org.fairscan.app.ui.Screen
|
import org.fairscan.app.ui.Screen
|
||||||
import org.fairscan.app.ui.components.rememberCameraPermissionState
|
import org.fairscan.app.ui.components.rememberCameraPermissionState
|
||||||
import org.fairscan.app.ui.screens.AboutScreen
|
|
||||||
import org.fairscan.app.ui.screens.DocumentScreen
|
import org.fairscan.app.ui.screens.DocumentScreen
|
||||||
import org.fairscan.app.ui.screens.LibrariesScreen
|
import org.fairscan.app.ui.screens.LibrariesScreen
|
||||||
|
import org.fairscan.app.ui.screens.about.AboutEvent
|
||||||
|
import org.fairscan.app.ui.screens.about.AboutScreen
|
||||||
|
import org.fairscan.app.ui.screens.about.AboutViewModel
|
||||||
import org.fairscan.app.ui.screens.camera.CameraEvent
|
import org.fairscan.app.ui.screens.camera.CameraEvent
|
||||||
import org.fairscan.app.ui.screens.camera.CameraScreen
|
import org.fairscan.app.ui.screens.camera.CameraScreen
|
||||||
import org.fairscan.app.ui.screens.camera.CameraViewModel
|
import org.fairscan.app.ui.screens.camera.CameraViewModel
|
||||||
@@ -74,6 +80,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
val homeViewModel: HomeViewModel by viewModels { appContainer.homeViewModelFactory }
|
val homeViewModel: HomeViewModel by viewModels { appContainer.homeViewModelFactory }
|
||||||
val cameraViewModel: CameraViewModel by viewModels { appContainer.cameraViewModelFactory }
|
val cameraViewModel: CameraViewModel by viewModels { appContainer.cameraViewModelFactory }
|
||||||
val exportViewModel: ExportViewModel by viewModels { appContainer.exportViewModelFactory }
|
val exportViewModel: ExportViewModel by viewModels { appContainer.exportViewModelFactory }
|
||||||
|
val aboutViewModel: AboutViewModel by viewModels { appContainer.aboutViewModelFactory }
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
exportViewModel.cleanUpOldPdfs(1000 * 3600)
|
exportViewModel.cleanUpOldPdfs(1000 * 3600)
|
||||||
}
|
}
|
||||||
@@ -118,6 +125,20 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val clipboard = LocalClipboard.current
|
||||||
|
val msgCopiedLogs = stringResource(R.string.copied_logs)
|
||||||
|
LaunchedEffect(aboutViewModel.events) {
|
||||||
|
aboutViewModel.events.collect { event ->
|
||||||
|
when (event) {
|
||||||
|
is AboutEvent.CopyLogs -> {
|
||||||
|
clipboard.setClipEntry(
|
||||||
|
ClipData.newPlainText("FairScan logs", event.logs).toClipEntry()
|
||||||
|
)
|
||||||
|
Toast.makeText(context, msgCopiedLogs, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FairScanTheme {
|
FairScanTheme {
|
||||||
val navigation = Navigation(
|
val navigation = Navigation(
|
||||||
@@ -180,7 +201,10 @@ class MainActivity : ComponentActivity() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Screen.Overlay.About -> {
|
is Screen.Overlay.About -> {
|
||||||
AboutScreen(onBack = navigation.back, onViewLibraries = navigation.toLibrariesScreen)
|
AboutScreen(
|
||||||
|
onBack = navigation.back,
|
||||||
|
onCopyLogs = { aboutViewModel.onCopyLogsClicked() },
|
||||||
|
onViewLibraries = navigation.toLibrariesScreen)
|
||||||
}
|
}
|
||||||
is Screen.Overlay.Libraries -> {
|
is Screen.Overlay.Libraries -> {
|
||||||
LibrariesScreen(onBack = navigation.back)
|
LibrariesScreen(onBack = navigation.back)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import java.io.File
|
|||||||
|
|
||||||
class LogRepository(private val file: File) {
|
class LogRepository(private val file: File) {
|
||||||
|
|
||||||
fun getLogs(): String = file.readText()
|
fun getLogs(): String = if (file.exists()) file.readText() else ""
|
||||||
|
|
||||||
fun log(tag: String, message: String, throwable: Throwable) {
|
fun log(tag: String, message: String, throwable: Throwable) {
|
||||||
val line = buildString {
|
val line = buildString {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.fairscan.app.ui.screens
|
package org.fairscan.app.ui.screens.about
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
@@ -32,6 +32,7 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
|
import androidx.compose.material.icons.filled.ContentCopy
|
||||||
import androidx.compose.material.icons.filled.Email
|
import androidx.compose.material.icons.filled.Email
|
||||||
import androidx.compose.material.icons.filled.Language
|
import androidx.compose.material.icons.filled.Language
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
@@ -69,7 +70,11 @@ import org.fairscan.app.ui.theme.FairScanTheme
|
|||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutScreen(onBack: () -> Unit, onViewLibraries: () -> Unit) {
|
fun AboutScreen(
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onCopyLogs: () -> Unit,
|
||||||
|
onViewLibraries: () -> Unit,
|
||||||
|
) {
|
||||||
val showLicenseDialog = rememberSaveable { mutableStateOf(false) }
|
val showLicenseDialog = rememberSaveable { mutableStateOf(false) }
|
||||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
BackHandler { onBack() }
|
BackHandler { onBack() }
|
||||||
@@ -81,7 +86,11 @@ fun AboutScreen(onBack: () -> Unit, onViewLibraries: () -> Unit) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
AboutContent(modifier = Modifier.padding(paddingValues), showLicenseDialog, onViewLibraries)
|
AboutContent(
|
||||||
|
modifier = Modifier.padding(paddingValues),
|
||||||
|
onCopyLogs,
|
||||||
|
showLicenseDialog,
|
||||||
|
onViewLibraries)
|
||||||
}
|
}
|
||||||
if (showLicenseDialog.value) {
|
if (showLicenseDialog.value) {
|
||||||
LicenseBottomSheet(sheetState, onDismiss = { showLicenseDialog.value = false })
|
LicenseBottomSheet(sheetState, onDismiss = { showLicenseDialog.value = false })
|
||||||
@@ -91,6 +100,7 @@ fun AboutScreen(onBack: () -> Unit, onViewLibraries: () -> Unit) {
|
|||||||
@Composable
|
@Composable
|
||||||
fun AboutContent(
|
fun AboutContent(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
onCopyLogs: () -> Unit,
|
||||||
showLicenseDialog: MutableState<Boolean>,
|
showLicenseDialog: MutableState<Boolean>,
|
||||||
onViewLibraries: () -> Unit,
|
onViewLibraries: () -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -142,12 +152,12 @@ fun AboutContent(
|
|||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
CopyLogsButton (onClick = onCopyLogs)
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(title = stringResource(R.string.license)) {
|
Section(title = stringResource(R.string.license)) {
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.licensed_under),
|
stringResource(R.string.licensed_under),
|
||||||
|
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.view_the_full_license),
|
text = stringResource(R.string.view_the_full_license),
|
||||||
@@ -156,7 +166,6 @@ fun AboutContent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Section(title = stringResource(R.string.libraries)) {
|
Section(title = stringResource(R.string.libraries)) {
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.libraries_intro) +
|
stringResource(R.string.libraries_intro) +
|
||||||
@@ -259,10 +268,29 @@ fun LicenseBottomSheet(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CopyLogsButton(onClick: () -> Unit) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable { onClick() }
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.ContentCopy,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
Text(stringResource(R.string.copy_logs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutScreenPreview() {
|
fun AboutScreenPreview() {
|
||||||
FairScanTheme {
|
FairScanTheme {
|
||||||
AboutScreen(onBack = {}, onViewLibraries = {})
|
AboutScreen(onBack = {}, onCopyLogs = {}, onViewLibraries = {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Pierre-Yves Nicolas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.fairscan.app.ui.screens.about
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.fairscan.app.AppContainer
|
||||||
|
import org.fairscan.app.BuildConfig
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
sealed interface AboutEvent {
|
||||||
|
data class CopyLogs(val logs: String) : AboutEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
class AboutViewModel(container: AppContainer): ViewModel() {
|
||||||
|
|
||||||
|
private val logRepository = container.logRepository
|
||||||
|
|
||||||
|
private val _events = MutableSharedFlow<AboutEvent>()
|
||||||
|
val events = _events.asSharedFlow()
|
||||||
|
|
||||||
|
fun onCopyLogsClicked() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val logs = buildFullLogs()
|
||||||
|
_events.emit(AboutEvent.CopyLogs(logs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildFullLogs(): String {
|
||||||
|
val header = buildString {
|
||||||
|
appendLine("FairScan diagnostics report")
|
||||||
|
appendLine("App version: ${BuildConfig.VERSION_NAME}")
|
||||||
|
appendLine("Android version: ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})")
|
||||||
|
appendLine("Generated: ${LocalDateTime.now()}")
|
||||||
|
appendLine()
|
||||||
|
appendLine("-- Application logs --")
|
||||||
|
appendLine()
|
||||||
|
}
|
||||||
|
return header + logRepository.getLogs()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="about">O aplikaci</string>
|
<string name="about">O aplikaci</string>
|
||||||
<string name="add_page">Přidat stránku</string>
|
<string name="add_page">Přidat stránku</string>
|
||||||
<string name="app_name" translatable="false">FairScan</string>
|
|
||||||
<string name="app_tagline">Jednoduchá a respektující aplikace pro skenování vašich dokumentů</string>
|
<string name="app_tagline">Jednoduchá a respektující aplikace pro skenování vašich dokumentů</string>
|
||||||
<string name="back">Zpět</string>
|
<string name="back">Zpět</string>
|
||||||
<string name="camera_permission_denied">Byl odepřen přístup k fotoaparátu</string>
|
<string name="camera_permission_denied">Byl odepřen přístup k fotoaparátu</string>
|
||||||
@@ -9,6 +8,8 @@
|
|||||||
<string name="cancel">Zrušit</string>
|
<string name="cancel">Zrušit</string>
|
||||||
<string name="clear_text">Smazat text</string>
|
<string name="clear_text">Smazat text</string>
|
||||||
<string name="contact">Kontakt</string>
|
<string name="contact">Kontakt</string>
|
||||||
|
<string name="copied_logs">Protokoly zkopírovány do schránky</string>
|
||||||
|
<string name="copy_logs">Kopírovat protokoly</string>
|
||||||
<string name="creating_pdf">Vytváření PDF…</string>
|
<string name="creating_pdf">Vytváření PDF…</string>
|
||||||
<string name="delete_page">Smazat stránku</string>
|
<string name="delete_page">Smazat stránku</string>
|
||||||
<string name="delete_page_warning">Chcete smazat tuto stránku?</string>
|
<string name="delete_page_warning">Chcete smazat tuto stránku?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">Abbrechen</string>
|
<string name="cancel">Abbrechen</string>
|
||||||
<string name="clear_text">Text löschen</string>
|
<string name="clear_text">Text löschen</string>
|
||||||
<string name="contact">Kontakt</string>
|
<string name="contact">Kontakt</string>
|
||||||
|
<string name="copied_logs">Logs in die Zwischenablage kopiert</string>
|
||||||
|
<string name="copy_logs">Logs kopieren</string>
|
||||||
<string name="creating_pdf">PDF wird erstellt…</string>
|
<string name="creating_pdf">PDF wird erstellt…</string>
|
||||||
<string name="delete_page">Seite löschen</string>
|
<string name="delete_page">Seite löschen</string>
|
||||||
<string name="delete_page_warning">Möchten Sie diese Seite löschen?</string>
|
<string name="delete_page_warning">Möchten Sie diese Seite löschen?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">Cancelar</string>
|
<string name="cancel">Cancelar</string>
|
||||||
<string name="clear_text">Borrar texto</string>
|
<string name="clear_text">Borrar texto</string>
|
||||||
<string name="contact">Contacto</string>
|
<string name="contact">Contacto</string>
|
||||||
|
<string name="copied_logs">Registros copiados al portapapeles</string>
|
||||||
|
<string name="copy_logs">Copiar registros</string>
|
||||||
<string name="creating_pdf">Creando PDF…</string>
|
<string name="creating_pdf">Creando PDF…</string>
|
||||||
<string name="delete_page">Eliminar página</string>
|
<string name="delete_page">Eliminar página</string>
|
||||||
<string name="delete_page_warning">¿Quieres eliminar esta página?</string>
|
<string name="delete_page_warning">¿Quieres eliminar esta página?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">Annuler</string>
|
<string name="cancel">Annuler</string>
|
||||||
<string name="contact">Contact</string>
|
<string name="contact">Contact</string>
|
||||||
<string name="clear_text">Effacer le text</string>
|
<string name="clear_text">Effacer le text</string>
|
||||||
|
<string name="copied_logs">Logs copiés dans le presse-papiers</string>
|
||||||
|
<string name="copy_logs">Copier les logs</string>
|
||||||
<string name="creating_pdf">Création du PDF…</string>
|
<string name="creating_pdf">Création du PDF…</string>
|
||||||
<string name="delete_page">Supprimer la page</string>
|
<string name="delete_page">Supprimer la page</string>
|
||||||
<string name="delete_page_warning">Voulez-vous supprimer cette page ?</string>
|
<string name="delete_page_warning">Voulez-vous supprimer cette page ?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">Annulla</string>
|
<string name="cancel">Annulla</string>
|
||||||
<string name="clear_text">Svuota testo</string>
|
<string name="clear_text">Svuota testo</string>
|
||||||
<string name="contact">Contatti</string>
|
<string name="contact">Contatti</string>
|
||||||
|
<string name="copied_logs">Log copiati negli appunti</string>
|
||||||
|
<string name="copy_logs">Copia log</string>
|
||||||
<string name="creating_pdf">Creazione PDF…</string>
|
<string name="creating_pdf">Creazione PDF…</string>
|
||||||
<string name="delete_page">Elimina pagina</string>
|
<string name="delete_page">Elimina pagina</string>
|
||||||
<string name="delete_page_warning">Vuoi eliminare questa pagina?</string>
|
<string name="delete_page_warning">Vuoi eliminare questa pagina?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">Cancelar</string>
|
<string name="cancel">Cancelar</string>
|
||||||
<string name="clear_text">Limpar texto</string>
|
<string name="clear_text">Limpar texto</string>
|
||||||
<string name="contact">Contato</string>
|
<string name="contact">Contato</string>
|
||||||
|
<string name="copied_logs">Registros copiados para a área de transferência</string>
|
||||||
|
<string name="copy_logs">Copiar registros</string>
|
||||||
<string name="creating_pdf">Criando PDF…</string>
|
<string name="creating_pdf">Criando PDF…</string>
|
||||||
<string name="delete_page">Excluir página</string>
|
<string name="delete_page">Excluir página</string>
|
||||||
<string name="delete_page_warning">Deseja excluir esta página?</string>
|
<string name="delete_page_warning">Deseja excluir esta página?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">Отмена</string>
|
<string name="cancel">Отмена</string>
|
||||||
<string name="clear_text">Стереть текст</string>
|
<string name="clear_text">Стереть текст</string>
|
||||||
<string name="contact">Контакты</string>
|
<string name="contact">Контакты</string>
|
||||||
|
<string name="copied_logs">Журналы скопированы в буфер обмена</string>
|
||||||
|
<string name="copy_logs">Копировать журналы</string>
|
||||||
<string name="creating_pdf">Создание PDF…</string>
|
<string name="creating_pdf">Создание PDF…</string>
|
||||||
<string name="delete_page">Удалить страницу</string>
|
<string name="delete_page">Удалить страницу</string>
|
||||||
<string name="delete_page_warning">Вы желаете удалить эту страницу?</string>
|
<string name="delete_page_warning">Вы желаете удалить эту страницу?</string>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<string name="cancel">取消</string>
|
<string name="cancel">取消</string>
|
||||||
<string name="clear_text">清除文字</string>
|
<string name="clear_text">清除文字</string>
|
||||||
<string name="contact">联系人</string>
|
<string name="contact">联系人</string>
|
||||||
|
<string name="copied_logs">日志已复制到剪贴板</string>
|
||||||
|
<string name="copy_logs">复制日志</string>
|
||||||
<string name="creating_pdf">正在创建 PDF…</string>
|
<string name="creating_pdf">正在创建 PDF…</string>
|
||||||
<string name="delete_page">删除页面</string>
|
<string name="delete_page">删除页面</string>
|
||||||
<string name="delete_page_warning">是否要删除此页面?</string>
|
<string name="delete_page_warning">是否要删除此页面?</string>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="clear_text">Clear text</string>
|
<string name="clear_text">Clear text</string>
|
||||||
<string name="contact">Contact</string>
|
<string name="contact">Contact</string>
|
||||||
|
<string name="copied_logs">Logs copied to clipboard</string>
|
||||||
|
<string name="copy_logs">Copy logs</string>
|
||||||
<string name="creating_pdf">Creating PDF…</string>
|
<string name="creating_pdf">Creating PDF…</string>
|
||||||
<string name="delete_page">Delete page</string>
|
<string name="delete_page">Delete page</string>
|
||||||
<string name="delete_page_warning">Do you want to delete this page?</string>
|
<string name="delete_page_warning">Do you want to delete this page?</string>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.assertj.core.api.Assertions.assertThat
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class LogRepositoryTest {
|
class LogRepositoryTest {
|
||||||
|
|
||||||
@@ -33,4 +34,12 @@ class LogRepositoryTest {
|
|||||||
assertThat(repo.getLogs()).contains("my exception")
|
assertThat(repo.getLogs()).contains("my exception")
|
||||||
print(repo.getLogs())
|
print(repo.getLogs())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun get_logs_with_file_not_yet_created() {
|
||||||
|
val file = File(folder.newFolder(), "log.txt")
|
||||||
|
val repo = LogRepository(file)
|
||||||
|
assertThat(file).doesNotExist()
|
||||||
|
assertThat(repo.getLogs()).isEmpty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user