Completa i18n Android su sheet, wizard, broadcast e login.
Selettore lingua con icona globo al login; dialog e bottom sheet (es. scegli squadra) tradotti; bump a 2.0.4-native. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -20,8 +20,8 @@ android {
|
||||
applicationId = "com.matchlivetv.match_live_tv"
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = 24
|
||||
versionName = "2.0.3-native"
|
||||
versionCode = 25
|
||||
versionName = "2.0.4-native"
|
||||
|
||||
val apiBaseUrl = project.findProperty("API_BASE_URL") as String?
|
||||
?: "https://www.matchlivetv.it"
|
||||
|
||||
+53
-27
@@ -52,6 +52,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -59,6 +60,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import coil.compose.AsyncImage
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.core.resolveMediaUrl
|
||||
import com.matchlivetv.match_live_tv.core.DeviceHealthSnapshot
|
||||
import com.matchlivetv.match_live_tv.core.ThermalLevel
|
||||
@@ -115,8 +117,8 @@ fun BroadcastControlsOverlay(
|
||||
AlertDialog(
|
||||
onDismissRequest = { showTerminateConfirm = false },
|
||||
containerColor = MatchColors.SurfaceElevated,
|
||||
title = { Text("Terminare la diretta?") },
|
||||
text = { Text("Lo streaming verrà chiuso per tutti gli spettatori.") },
|
||||
title = { Text(stringResource(R.string.broadcast_terminate_title)) },
|
||||
text = { Text(stringResource(R.string.broadcast_terminate_message)) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
@@ -124,12 +126,12 @@ fun BroadcastControlsOverlay(
|
||||
onTerminate()
|
||||
},
|
||||
) {
|
||||
Text("TERMINA", color = MatchColors.PrimaryRed)
|
||||
Text(stringResource(R.string.broadcast_terminate_confirm), color = MatchColors.PrimaryRed)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showTerminateConfirm = false }) {
|
||||
Text("Annulla", color = MatchColors.TextSecondary)
|
||||
Text(stringResource(R.string.action_cancel), color = MatchColors.TextSecondary)
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -158,7 +160,11 @@ fun BroadcastControlsOverlay(
|
||||
) {
|
||||
SideIconButton(
|
||||
icon = if (controlsVisible) Icons.Default.VisibilityOff else Icons.Default.Visibility,
|
||||
contentDescription = if (controlsVisible) "Nascondi controlli" else "Mostra controlli",
|
||||
contentDescription = if (controlsVisible) {
|
||||
stringResource(R.string.broadcast_hide_controls_cd)
|
||||
} else {
|
||||
stringResource(R.string.broadcast_show_controls_cd)
|
||||
},
|
||||
onClick = onToggleControls,
|
||||
)
|
||||
BroadcastTelemetryPanel(
|
||||
@@ -180,26 +186,26 @@ fun BroadcastControlsOverlay(
|
||||
) {
|
||||
SideIconButton(
|
||||
icon = Icons.Default.Share,
|
||||
contentDescription = "Condividi diretta",
|
||||
contentDescription = stringResource(R.string.broadcast_share_live_cd),
|
||||
onClick = onShareLive,
|
||||
enabled = shareLiveEnabled,
|
||||
)
|
||||
SideIconButton(
|
||||
icon = Icons.Default.Videocam,
|
||||
contentDescription = "Condividi link regia",
|
||||
contentDescription = stringResource(R.string.broadcast_share_regia_cd),
|
||||
onClick = onShareRegia,
|
||||
)
|
||||
if (onCloseSet != null) {
|
||||
SideIconButton(
|
||||
icon = Icons.Default.Check,
|
||||
contentDescription = "Chiudi set",
|
||||
contentDescription = stringResource(R.string.score_action_close_set),
|
||||
onClick = onCloseSet,
|
||||
)
|
||||
}
|
||||
if (onAdvancePeriod != null) {
|
||||
SideIconButton(
|
||||
icon = Icons.Default.SkipNext,
|
||||
contentDescription = "Periodo successivo",
|
||||
contentDescription = stringResource(R.string.broadcast_next_period_cd),
|
||||
onClick = onAdvancePeriod,
|
||||
)
|
||||
}
|
||||
@@ -213,13 +219,17 @@ fun BroadcastControlsOverlay(
|
||||
) {
|
||||
SideIconButton(
|
||||
icon = if (isPaused) Icons.Default.PlayArrow else Icons.Default.Pause,
|
||||
contentDescription = if (isPaused) "Riprendi diretta" else "Pausa diretta",
|
||||
contentDescription = if (isPaused) {
|
||||
stringResource(R.string.broadcast_resume_cd)
|
||||
} else {
|
||||
stringResource(R.string.broadcast_pause_cd)
|
||||
},
|
||||
onClick = onPauseOrResume,
|
||||
highlighted = isPaused,
|
||||
)
|
||||
SideIconButton(
|
||||
icon = Icons.Default.Stop,
|
||||
contentDescription = "Termina diretta",
|
||||
contentDescription = stringResource(R.string.broadcast_terminate_cd),
|
||||
onClick = { showTerminateConfirm = true },
|
||||
danger = true,
|
||||
)
|
||||
@@ -232,7 +242,7 @@ fun BroadcastControlsOverlay(
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
TeamScoreColumn(
|
||||
teamLabel = "CASA",
|
||||
teamLabel = stringResource(R.string.broadcast_team_home_label),
|
||||
teamName = homeName,
|
||||
accentColor = homeAccentColor,
|
||||
logoUrl = homeLogoUrl,
|
||||
@@ -251,7 +261,7 @@ fun BroadcastControlsOverlay(
|
||||
pointsTarget = pointsTarget,
|
||||
)
|
||||
TeamScoreColumn(
|
||||
teamLabel = "OSPITE",
|
||||
teamLabel = stringResource(R.string.broadcast_team_away_label),
|
||||
teamName = awayName,
|
||||
accentColor = awayAccentColor,
|
||||
logoUrl = awayLogoUrl,
|
||||
@@ -289,7 +299,11 @@ private fun BroadcastTelemetryPanel(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
Text(
|
||||
if (cableConnected) "Tabellone OK" else "Tabellone offline",
|
||||
if (cableConnected) {
|
||||
stringResource(R.string.broadcast_scoreboard_connected)
|
||||
} else {
|
||||
stringResource(R.string.broadcast_scoreboard_offline)
|
||||
},
|
||||
style = labelStyle,
|
||||
color = if (cableConnected) MatchColors.SuccessGreen else MatchColors.TextSecondary,
|
||||
)
|
||||
@@ -388,7 +402,11 @@ private fun ScoreCenterPanel(
|
||||
when (boardType) {
|
||||
"basket", "timed" -> {
|
||||
Text(
|
||||
score.periodLabel ?: if (boardType == "basket") "Q${score.period}" else "${score.period}° tempo",
|
||||
score.periodLabel ?: if (boardType == "basket") {
|
||||
"Q${score.period}"
|
||||
} else {
|
||||
stringResource(R.string.broadcast_period_label_timed, score.period)
|
||||
},
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
@@ -396,13 +414,13 @@ private fun ScoreCenterPanel(
|
||||
"generic" -> Unit
|
||||
else -> {
|
||||
Text(
|
||||
"Set ${score.currentSet} · $pointsTarget pt",
|
||||
stringResource(R.string.broadcast_set_progress, score.currentSet, pointsTarget),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
if (score.homeSets > 0 || score.awaySets > 0) {
|
||||
Text(
|
||||
"Set vinti ${score.homeSets}-${score.awaySets}",
|
||||
stringResource(R.string.broadcast_sets_won, score.homeSets, score.awaySets),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
@@ -450,7 +468,15 @@ private fun TeamScoreColumn(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
val teamSide = if (alignEnd) "ospite" else "casa"
|
||||
val teamSide = if (alignEnd) {
|
||||
stringResource(R.string.broadcast_side_away)
|
||||
} else {
|
||||
stringResource(R.string.broadcast_side_home)
|
||||
}
|
||||
val addPointTooltip = stringResource(R.string.broadcast_tooltip_add_point, teamSide)
|
||||
val removePointTooltip = stringResource(R.string.broadcast_tooltip_remove_point, teamSide)
|
||||
val plus2Tooltip = stringResource(R.string.broadcast_tooltip_plus_side, 2, teamSide)
|
||||
val plus3Tooltip = stringResource(R.string.broadcast_tooltip_plus_side, 3, teamSide)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = if (alignEnd) Arrangement.End else Arrangement.Start,
|
||||
@@ -459,33 +485,33 @@ private fun TeamScoreColumn(
|
||||
if (alignEnd) {
|
||||
if (showBasketButtons) {
|
||||
onPlus3?.let {
|
||||
ScoreIconButton(label = "+3", tooltip = "+3 $teamSide", onClick = it, primary = true)
|
||||
ScoreIconButton(label = "+3", tooltip = plus3Tooltip, onClick = it, primary = true)
|
||||
}
|
||||
onPlus2?.let {
|
||||
ScoreIconButton(label = "+2", tooltip = "+2 $teamSide", onClick = it, primary = true)
|
||||
ScoreIconButton(label = "+2", tooltip = plus2Tooltip, onClick = it, primary = true)
|
||||
}
|
||||
}
|
||||
ScoreIconButton(
|
||||
label = "+1",
|
||||
tooltip = "Aggiungi punto $teamSide",
|
||||
tooltip = addPointTooltip,
|
||||
onClick = onPlus,
|
||||
primary = !showBasketButtons,
|
||||
)
|
||||
ScoreIconButton(label = "−", tooltip = "Togli punto $teamSide", onClick = onMinus)
|
||||
ScoreIconButton(label = "−", tooltip = removePointTooltip, onClick = onMinus)
|
||||
} else {
|
||||
ScoreIconButton(label = "−", tooltip = "Togli punto $teamSide", onClick = onMinus)
|
||||
ScoreIconButton(label = "−", tooltip = removePointTooltip, onClick = onMinus)
|
||||
ScoreIconButton(
|
||||
label = "+1",
|
||||
tooltip = "Aggiungi punto $teamSide",
|
||||
tooltip = addPointTooltip,
|
||||
onClick = onPlus,
|
||||
primary = !showBasketButtons,
|
||||
)
|
||||
if (showBasketButtons) {
|
||||
onPlus2?.let {
|
||||
ScoreIconButton(label = "+2", tooltip = "+2 $teamSide", onClick = it, primary = true)
|
||||
ScoreIconButton(label = "+2", tooltip = plus2Tooltip, onClick = it, primary = true)
|
||||
}
|
||||
onPlus3?.let {
|
||||
ScoreIconButton(label = "+3", tooltip = "+3 $teamSide", onClick = it, primary = true)
|
||||
ScoreIconButton(label = "+3", tooltip = plus3Tooltip, onClick = it, primary = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -676,7 +702,7 @@ fun shareBroadcastLink(context: Context, url: String, subject: String) {
|
||||
putExtra(Intent.EXTRA_TEXT, url)
|
||||
putExtra(Intent.EXTRA_SUBJECT, subject)
|
||||
},
|
||||
"Condividi",
|
||||
context.getString(R.string.broadcast_share_chooser_title),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
+41
-22
@@ -27,8 +27,10 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.core.DeviceTelemetry
|
||||
import com.matchlivetv.match_live_tv.core.parseColorHex
|
||||
import com.matchlivetv.match_live_tv.core.resolveMediaUrl
|
||||
@@ -99,6 +101,8 @@ fun BroadcastScreen(
|
||||
onFinished()
|
||||
}
|
||||
|
||||
val genericError = context.getString(R.string.common_error_generic)
|
||||
|
||||
suspend fun pauseStream() {
|
||||
if (pauseInFlight) return
|
||||
pauseInFlight = true
|
||||
@@ -106,9 +110,11 @@ fun BroadcastScreen(
|
||||
val updated = container.sessionRepository.pauseSession(sessionId)
|
||||
session = updated
|
||||
container.broadcastCoordinator.engine.pauseBroadcast()
|
||||
snackbar.showSnackbar("Diretta in pausa")
|
||||
snackbar.showSnackbar(context.getString(R.string.broadcast_snackbar_paused))
|
||||
} catch (e: Exception) {
|
||||
snackbar.showSnackbar("Pausa: ${e.message ?: "errore"}")
|
||||
snackbar.showSnackbar(
|
||||
context.getString(R.string.broadcast_snackbar_pause_error, e.message ?: genericError),
|
||||
)
|
||||
} finally {
|
||||
pauseInFlight = false
|
||||
}
|
||||
@@ -126,9 +132,11 @@ fun BroadcastScreen(
|
||||
}
|
||||
updated = container.sessionRepository.fetchSession(sessionId)
|
||||
session = updated
|
||||
snackbar.showSnackbar("Diretta ripresa")
|
||||
snackbar.showSnackbar(context.getString(R.string.broadcast_snackbar_resumed))
|
||||
} catch (e: Exception) {
|
||||
snackbar.showSnackbar("Ripresa: ${e.message ?: "errore"}")
|
||||
snackbar.showSnackbar(
|
||||
context.getString(R.string.broadcast_snackbar_resume_error, e.message ?: genericError),
|
||||
)
|
||||
} finally {
|
||||
resumeInFlight = false
|
||||
}
|
||||
@@ -138,7 +146,7 @@ fun BroadcastScreen(
|
||||
container.broadcastCoordinator.engine.pauseBroadcast()
|
||||
session = runCatching { container.sessionRepository.fetchSession(sessionId) }
|
||||
.getOrNull() ?: session?.copy(status = "paused")
|
||||
snackbar.showSnackbar("Pausa dalla regia")
|
||||
snackbar.showSnackbar(context.getString(R.string.broadcast_snackbar_paused_remote))
|
||||
}
|
||||
|
||||
suspend fun applyRemoteResume() {
|
||||
@@ -150,9 +158,11 @@ fun BroadcastScreen(
|
||||
try {
|
||||
session = current
|
||||
container.broadcastCoordinator.engine.resumeBroadcast(broadcastConfig(current))
|
||||
snackbar.showSnackbar("Ripresa dalla regia")
|
||||
snackbar.showSnackbar(context.getString(R.string.broadcast_snackbar_resumed_remote))
|
||||
} catch (e: Exception) {
|
||||
snackbar.showSnackbar("Ripresa RTMP: ${e.message ?: "errore"}")
|
||||
snackbar.showSnackbar(
|
||||
context.getString(R.string.broadcast_snackbar_resume_rtmp_error, e.message ?: genericError),
|
||||
)
|
||||
} finally {
|
||||
resumeInFlight = false
|
||||
}
|
||||
@@ -162,7 +172,7 @@ fun BroadcastScreen(
|
||||
container.sessionCable.disconnect()
|
||||
container.broadcastCoordinator.engine.stopBroadcast()
|
||||
container.broadcastCoordinator.stopService()
|
||||
snackbar.showSnackbar("Diretta chiusa dalla regia")
|
||||
snackbar.showSnackbar(context.getString(R.string.broadcast_snackbar_closed_remote))
|
||||
onFinished()
|
||||
}
|
||||
|
||||
@@ -195,12 +205,12 @@ fun BroadcastScreen(
|
||||
container.broadcastCoordinator.startService()
|
||||
val url = loaded.rtmpIngestUrl
|
||||
if (url.isNullOrBlank()) {
|
||||
error("URL RTMP mancante")
|
||||
error(context.getString(R.string.broadcast_error_rtmp_missing))
|
||||
} else if (!loaded.isPaused) {
|
||||
container.broadcastCoordinator.engine.startBroadcast(broadcastConfig(loaded))
|
||||
}
|
||||
}.onFailure {
|
||||
error = it.message ?: "Sessione non disponibile"
|
||||
error = it.message ?: context.getString(R.string.broadcast_error_session_unavailable)
|
||||
}
|
||||
loading = false
|
||||
}
|
||||
@@ -241,7 +251,7 @@ fun BroadcastScreen(
|
||||
awayScore = score.awayPoints,
|
||||
periodLabel = score.periodLabel ?: when (overlayKind) {
|
||||
OverlayKind.BASKET -> "Q${score.period}"
|
||||
else -> "${score.period}° tempo"
|
||||
else -> context.getString(R.string.broadcast_period_label_timed, score.period)
|
||||
},
|
||||
homeAccentColor = homeColor,
|
||||
awayAccentColor = awayColor,
|
||||
@@ -330,11 +340,11 @@ fun BroadcastScreen(
|
||||
|
||||
val isPaused = session?.isPaused == true || metrics.phase == BroadcastPhase.PAUSED
|
||||
val statusText = when {
|
||||
isPaused -> "PAUSA"
|
||||
metrics.phase == BroadcastPhase.LIVE -> "IN DIRETTA"
|
||||
metrics.phase == BroadcastPhase.CONNECTING -> "CONNESSIONE…"
|
||||
metrics.phase == BroadcastPhase.RECONNECTING -> "RICONNESSIONE…"
|
||||
metrics.phase == BroadcastPhase.ERROR -> metrics.lastError ?: "ERRORE"
|
||||
isPaused -> stringResource(R.string.broadcast_status_paused)
|
||||
metrics.phase == BroadcastPhase.LIVE -> stringResource(R.string.broadcast_status_live)
|
||||
metrics.phase == BroadcastPhase.CONNECTING -> stringResource(R.string.broadcast_status_connecting)
|
||||
metrics.phase == BroadcastPhase.RECONNECTING -> stringResource(R.string.broadcast_status_reconnecting)
|
||||
metrics.phase == BroadcastPhase.ERROR -> metrics.lastError ?: stringResource(R.string.broadcast_status_error_fallback)
|
||||
else -> "PREVIEW"
|
||||
}
|
||||
val statusColor = when {
|
||||
@@ -353,7 +363,8 @@ fun BroadcastScreen(
|
||||
container.scoreController.applyAction(action)
|
||||
}
|
||||
val shareUrl = currentSession?.watchShareUrl()
|
||||
val shareSubject = currentMatch?.let { "${it.teamName} vs ${it.opponentName}" } ?: "Diretta Match Live TV"
|
||||
val shareSubject = currentMatch?.let { "${it.teamName} vs ${it.opponentName}" }
|
||||
?: stringResource(R.string.broadcast_share_subject_fallback)
|
||||
|
||||
currentMatch?.let { m ->
|
||||
ScoreDialogRouter(
|
||||
@@ -383,12 +394,12 @@ fun BroadcastScreen(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
"Consenti camera e microfono per andare in diretta",
|
||||
stringResource(R.string.broadcast_permissions_required),
|
||||
color = MatchColors.AccentYellow,
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
MatchPrimaryButton(
|
||||
label = "CONCEDI PERMESSI",
|
||||
label = stringResource(R.string.broadcast_permissions_grant_action),
|
||||
onClick = permissions.request,
|
||||
)
|
||||
}
|
||||
@@ -505,7 +516,9 @@ fun BroadcastScreen(
|
||||
onShareLive = {
|
||||
val url = shareUrl
|
||||
if (url.isNullOrBlank()) {
|
||||
scope.launch { snackbar.showSnackbar("Link diretta non ancora disponibile") }
|
||||
scope.launch {
|
||||
snackbar.showSnackbar(context.getString(R.string.broadcast_share_link_unavailable))
|
||||
}
|
||||
} else {
|
||||
shareBroadcastLink(context, url, shareSubject)
|
||||
}
|
||||
@@ -514,10 +527,16 @@ fun BroadcastScreen(
|
||||
scope.launch {
|
||||
runCatching { container.sessionRepository.createRegiaLink(sessionId) }
|
||||
.onSuccess { url ->
|
||||
shareBroadcastLink(context, url, "Link regia — $shareSubject")
|
||||
shareBroadcastLink(
|
||||
context,
|
||||
url,
|
||||
context.getString(R.string.broadcast_share_regia_subject, shareSubject),
|
||||
)
|
||||
}
|
||||
.onFailure {
|
||||
snackbar.showSnackbar(it.message ?: "Errore link regia")
|
||||
snackbar.showSnackbar(
|
||||
it.message ?: context.getString(R.string.broadcast_error_regia_link),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+16
-5
@@ -16,9 +16,11 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.domain.ScoreState
|
||||
import com.matchlivetv.match_live_tv.ui.components.MatchPrimaryButton
|
||||
import com.matchlivetv.match_live_tv.ui.components.MatchSecondaryButton
|
||||
@@ -59,7 +61,7 @@ fun LiveScoreControls(
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Text(
|
||||
"$pointsTarget pt",
|
||||
stringResource(R.string.broadcast_points_target, pointsTarget),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
modifier = Modifier.padding(top = 24.dp).padding(horizontal = 8.dp),
|
||||
@@ -74,7 +76,7 @@ fun LiveScoreControls(
|
||||
}
|
||||
Spacer(Modifier.height(10.dp))
|
||||
MatchSecondaryButton(
|
||||
label = "CHIUDI SET",
|
||||
label = stringResource(R.string.broadcast_close_set_button),
|
||||
onClick = onCloseSet,
|
||||
)
|
||||
}
|
||||
@@ -132,7 +134,11 @@ private fun ScoreOverlayBar(
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(homeName, style = MaterialTheme.typography.labelMedium, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||
Text("${score.homeSets} set", style = MaterialTheme.typography.labelSmall, color = MatchColors.TextSecondary)
|
||||
Text(
|
||||
stringResource(R.string.broadcast_team_sets_count, score.homeSets),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
}
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
@@ -140,14 +146,19 @@ private fun ScoreOverlayBar(
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
Text(
|
||||
"Set ${score.currentSet} · $pointsTarget pt",
|
||||
stringResource(R.string.broadcast_set_progress, score.currentSet, pointsTarget),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
}
|
||||
Column(Modifier.weight(1f), horizontalAlignment = Alignment.End) {
|
||||
Text(awayName, style = MaterialTheme.typography.labelMedium, maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.End)
|
||||
Text("${score.awaySets} set", style = MaterialTheme.typography.labelSmall, color = MatchColors.TextSecondary, textAlign = TextAlign.End)
|
||||
Text(
|
||||
stringResource(R.string.broadcast_team_sets_count, score.awaySets),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MatchColors.TextSecondary,
|
||||
textAlign = TextAlign.End,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-18
@@ -6,6 +6,8 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.domain.ScoringSide
|
||||
import com.matchlivetv.match_live_tv.ui.theme.MatchColors
|
||||
|
||||
@@ -19,21 +21,18 @@ fun SetWonDialog(
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismiss(false) },
|
||||
containerColor = MatchColors.Surface,
|
||||
title = { Text("Set concluso") },
|
||||
title = { Text(stringResource(R.string.score_set_won_title)) },
|
||||
text = {
|
||||
Text(
|
||||
"$winnerName vince il set $homePoints-$awayPoints.\n\n" +
|
||||
"Chiudere il set e passare al successivo?",
|
||||
)
|
||||
Text(stringResource(R.string.score_set_won_message, winnerName, homePoints, awayPoints))
|
||||
},
|
||||
confirmButton = {
|
||||
FilledTonalButton(onClick = { onDismiss(true) }) {
|
||||
Text("Chiudi set", color = Color.Black)
|
||||
Text(stringResource(R.string.score_action_close_set), color = Color.Black)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { onDismiss(false) }) {
|
||||
Text("Continua a segnare")
|
||||
Text(stringResource(R.string.score_action_continue_scoring))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -44,18 +43,18 @@ fun CloseSetAnywayDialog(onDismiss: (confirmed: Boolean) -> Unit) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismiss(false) },
|
||||
containerColor = MatchColors.Surface,
|
||||
title = { Text("Chiudi set") },
|
||||
title = { Text(stringResource(R.string.score_action_close_set)) },
|
||||
text = {
|
||||
Text("Il punteggio non soddisfa ancora le regole del torneo. Chiudere il set comunque?")
|
||||
Text(stringResource(R.string.score_close_set_anyway_message))
|
||||
},
|
||||
confirmButton = {
|
||||
FilledTonalButton(onClick = { onDismiss(true) }) {
|
||||
Text("Chiudi comunque")
|
||||
Text(stringResource(R.string.score_action_close_anyway))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { onDismiss(false) }) {
|
||||
Text("Annulla")
|
||||
Text(stringResource(R.string.action_cancel))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -71,21 +70,18 @@ fun MatchWonDialog(
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismiss(false) },
|
||||
containerColor = MatchColors.Surface,
|
||||
title = { Text("Partita terminata") },
|
||||
title = { Text(stringResource(R.string.score_match_won_title)) },
|
||||
text = {
|
||||
Text(
|
||||
"$winnerName vince la partita ($homeSets-$awaySets set).\n\n" +
|
||||
"Chiudere definitivamente la diretta?",
|
||||
)
|
||||
Text(stringResource(R.string.score_match_won_message, winnerName, homeSets, awaySets))
|
||||
},
|
||||
confirmButton = {
|
||||
FilledTonalButton(onClick = { onDismiss(true) }) {
|
||||
Text("Chiudi diretta", color = Color.White)
|
||||
Text(stringResource(R.string.score_action_close_live), color = Color.White)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { onDismiss(false) }) {
|
||||
Text("Continua in onda")
|
||||
Text(stringResource(R.string.score_action_continue_live))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
+16
-7
@@ -1,5 +1,6 @@
|
||||
package com.matchlivetv.match_live_tv.ui.login
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -10,6 +11,7 @@ import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material.icons.filled.Visibility
|
||||
import androidx.compose.material.icons.filled.VisibilityOff
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -17,7 +19,6 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.OutlinedTextFieldDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -85,6 +86,18 @@ fun LoginScreen(
|
||||
if (showLanguagePicker) {
|
||||
LanguagePickerDialog(onDismiss = { showLanguagePicker = false })
|
||||
}
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
IconButton(
|
||||
onClick = { showLanguagePicker = true },
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Language,
|
||||
contentDescription = stringResource(R.string.language_label),
|
||||
tint = MatchColors.TextSecondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
@@ -92,11 +105,7 @@ fun LoginScreen(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
MatchLiveWordmark(showSlogan = true)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
TextButton(onClick = { showLanguagePicker = true }) {
|
||||
Text(stringResource(R.string.language_label), color = MatchColors.TextSecondary)
|
||||
}
|
||||
Spacer(Modifier.height(32.dp))
|
||||
Spacer(Modifier.height(48.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.login_submit).uppercase(),
|
||||
style = androidx.compose.material3.MaterialTheme.typography.headlineMedium,
|
||||
@@ -106,7 +115,7 @@ fun LoginScreen(
|
||||
value = email,
|
||||
onValueChange = { email = it },
|
||||
label = { Text(stringResource(R.string.login_email)) },
|
||||
placeholder = { Text("coach@squadra.it") },
|
||||
placeholder = { Text(stringResource(R.string.login_email_placeholder)) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
|
||||
+76
-49
@@ -52,7 +52,6 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
@@ -77,8 +76,13 @@ data class ScheduleMatchInput(
|
||||
val location: String?,
|
||||
)
|
||||
|
||||
private val sheetDateFormat =
|
||||
DateTimeFormatter.ofPattern("EEE d MMM yyyy · HH:mm", Locale.ITALY)
|
||||
@Composable
|
||||
private fun sheetDateFormatter(): DateTimeFormatter {
|
||||
val locale = LocalContext.current.resources.configuration.locales[0] ?: Locale.getDefault()
|
||||
return remember(locale) {
|
||||
DateTimeFormatter.ofPattern("EEE d MMM yyyy · HH:mm", locale)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -92,24 +96,24 @@ fun NewMatchBottomSheet(
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
) {
|
||||
Column(Modifier.padding(horizontal = 20.dp, vertical = 12.dp)) {
|
||||
Text("Nuova partita", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.sheet_new_match_title), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text(
|
||||
"Programma in anticipo o avvia la configurazione diretta subito.",
|
||||
stringResource(R.string.sheet_new_match_lead),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(Modifier.height(20.dp))
|
||||
SheetOptionTile(
|
||||
icon = { Icon(Icons.Default.EventAvailable, null, tint = MatchColors.PrimaryRed) },
|
||||
title = "Programma partita",
|
||||
subtitle = "Data, ora e avversario — visibile anche sul sito",
|
||||
title = stringResource(R.string.sheet_schedule_option),
|
||||
subtitle = stringResource(R.string.sheet_schedule_option_sub),
|
||||
onClick = { onChoice(NewMatchChoice.Schedule) },
|
||||
)
|
||||
Spacer(Modifier.height(10.dp))
|
||||
SheetOptionTile(
|
||||
icon = { Icon(Icons.Default.PlayCircleOutline, null, tint = MatchColors.PrimaryRed) },
|
||||
title = "Avvia subito",
|
||||
subtitle = "Crea la partita e passa al wizard senza orario",
|
||||
title = stringResource(R.string.sheet_quick_option),
|
||||
subtitle = stringResource(R.string.sheet_quick_option_sub),
|
||||
onClick = { onChoice(NewMatchChoice.QuickStart) },
|
||||
)
|
||||
Spacer(Modifier.height(24.dp))
|
||||
@@ -125,6 +129,7 @@ fun ScheduleMatchBottomSheet(
|
||||
onSubmit: (ScheduleMatchInput) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val dateFormat = sheetDateFormatter()
|
||||
var opponent by remember { mutableStateOf("") }
|
||||
var location by remember { mutableStateOf("") }
|
||||
var scheduledAt by remember {
|
||||
@@ -159,28 +164,27 @@ fun ScheduleMatchBottomSheet(
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
) {
|
||||
Column(Modifier.padding(horizontal = 20.dp, vertical = 12.dp)) {
|
||||
Text("Programma partita", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.sheet_schedule_title), style = MaterialTheme.typography.headlineMedium)
|
||||
if (!teamName.isNullOrBlank()) {
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Text(teamName, color = MatchColors.PrimaryRed, style = MaterialTheme.typography.titleMedium)
|
||||
}
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text(
|
||||
"La diretta non parte ora: comparirà sul sito con data e ora. " +
|
||||
"Avvierai lo streaming dall'app quando sei in palestra.",
|
||||
stringResource(R.string.sheet_schedule_lead),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(Modifier.height(20.dp))
|
||||
MatchOutlinedField(
|
||||
value = opponent,
|
||||
onValueChange = { opponent = it },
|
||||
label = "Avversario",
|
||||
label = stringResource(R.string.sheet_opponent),
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
MatchOutlinedField(
|
||||
value = location,
|
||||
onValueChange = { location = it },
|
||||
label = "Luogo (opzionale)",
|
||||
label = stringResource(R.string.sheet_location_optional),
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Row(
|
||||
@@ -191,9 +195,9 @@ fun ScheduleMatchBottomSheet(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text("Data e ora", style = MaterialTheme.typography.bodyMedium)
|
||||
Text(stringResource(R.string.sheet_date_time), style = MaterialTheme.typography.bodyMedium)
|
||||
Text(
|
||||
scheduledAt.format(sheetDateFormat),
|
||||
scheduledAt.format(dateFormat),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
@@ -201,7 +205,7 @@ fun ScheduleMatchBottomSheet(
|
||||
}
|
||||
Spacer(Modifier.height(20.dp))
|
||||
MatchPrimaryButton(
|
||||
label = "SALVA IN PROGRAMMA",
|
||||
label = stringResource(R.string.sheet_save_schedule),
|
||||
onClick = {
|
||||
val name = opponent.trim()
|
||||
if (name.isEmpty()) return@MatchPrimaryButton
|
||||
@@ -239,10 +243,10 @@ fun SelectMatchBottomSheet(
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
) {
|
||||
Column(Modifier.padding(horizontal = 20.dp, vertical = 12.dp)) {
|
||||
Text("Scegli partita", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.sheet_choose_match), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text(
|
||||
"Partite già programmate sul sito o in app.",
|
||||
stringResource(R.string.sheet_choose_match_lead),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
@@ -251,7 +255,12 @@ fun SelectMatchBottomSheet(
|
||||
modifier = Modifier.height(360.dp),
|
||||
) {
|
||||
if (scheduled.isNotEmpty()) {
|
||||
item { Text("Programmate", style = MaterialTheme.typography.labelLarge) }
|
||||
item {
|
||||
Text(
|
||||
stringResource(R.string.sheet_section_scheduled),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
)
|
||||
}
|
||||
items(scheduled, key = { it.id }) { match ->
|
||||
SelectMatchTile(match, now) { onSelect(match) }
|
||||
}
|
||||
@@ -259,7 +268,10 @@ fun SelectMatchBottomSheet(
|
||||
if (unscheduled.isNotEmpty()) {
|
||||
item {
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text("Senza orario", style = MaterialTheme.typography.labelLarge)
|
||||
Text(
|
||||
stringResource(R.string.sheet_section_unscheduled),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
)
|
||||
}
|
||||
items(unscheduled, key = { it.id }) { match ->
|
||||
SelectMatchTile(match, now) { onSelect(match) }
|
||||
@@ -285,7 +297,7 @@ fun TeamPickerBottomSheet(
|
||||
) {
|
||||
Column(Modifier.padding(bottom = 24.dp)) {
|
||||
Text(
|
||||
"Scegli squadra",
|
||||
stringResource(R.string.sheet_choose_team),
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
modifier = Modifier.padding(horizontal = 20.dp, vertical = 16.dp),
|
||||
)
|
||||
@@ -329,7 +341,7 @@ fun ResumeSessionBottomSheet(
|
||||
containerColor = MatchColors.Surface,
|
||||
) {
|
||||
Column(Modifier.padding(horizontal = 20.dp, vertical = 16.dp)) {
|
||||
Text("Diretta in corso", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.sheet_live_in_progress), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Text(
|
||||
"${match.teamName} vs ${match.opponentName}",
|
||||
@@ -337,19 +349,29 @@ fun ResumeSessionBottomSheet(
|
||||
)
|
||||
match.activeSessionStatus?.let { status ->
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text("Stato: $status", color = MatchColors.PrimaryRed, style = MaterialTheme.typography.labelLarge)
|
||||
Text(
|
||||
stringResource(R.string.sheet_status, status),
|
||||
color = MatchColors.PrimaryRed,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(20.dp))
|
||||
if (match.canResumeCamera) {
|
||||
MatchPrimaryButton(label = "RIPRENDI CAMERA E TRASMETTI", onClick = onResumeCamera)
|
||||
MatchPrimaryButton(
|
||||
label = stringResource(R.string.sheet_resume_camera),
|
||||
onClick = onResumeCamera,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
if (match.activeSessionStatus == "idle") {
|
||||
MatchSecondaryButton(label = "CONTINUA CONFIGURAZIONE", onClick = onContinueSetup)
|
||||
MatchSecondaryButton(
|
||||
label = stringResource(R.string.sheet_continue_setup),
|
||||
onClick = onContinueSetup,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
TextButton(onClick = onDismiss, modifier = Modifier.fillMaxWidth()) {
|
||||
Text("Annulla", color = MatchColors.TextSecondary)
|
||||
Text(stringResource(R.string.action_cancel), color = MatchColors.TextSecondary)
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
@@ -364,21 +386,21 @@ fun ConfigureScheduledMatchDialog(
|
||||
AlertDialog(
|
||||
onDismissRequest = onLater,
|
||||
containerColor = MatchColors.Surface,
|
||||
title = { Text("Configurare ora?") },
|
||||
title = { Text(stringResource(R.string.sheet_configure_now_title)) },
|
||||
text = {
|
||||
Text(
|
||||
"Puoi preparare la trasmissione subito, oppure tornare quando sei in palestra.",
|
||||
stringResource(R.string.sheet_configure_now_body),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = onConfigure) {
|
||||
Text("Configura", color = MatchColors.PrimaryRed)
|
||||
Text(stringResource(R.string.sheet_configure), color = MatchColors.PrimaryRed)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onLater) {
|
||||
Text("Più tardi", color = MatchColors.TextSecondary)
|
||||
Text(stringResource(R.string.sheet_later), color = MatchColors.TextSecondary)
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -393,22 +415,21 @@ fun DeleteMatchDialog(
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
containerColor = MatchColors.Surface,
|
||||
title = { Text("Elimina partita") },
|
||||
title = { Text(stringResource(R.string.sheet_delete_match_title)) },
|
||||
text = {
|
||||
Text(
|
||||
"Eliminare «${match.teamName} vs ${match.opponentName}»?\n\n" +
|
||||
"L'operazione non si può annullare.",
|
||||
stringResource(R.string.sheet_delete_match_body, match.teamName, match.opponentName),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = onConfirm) {
|
||||
Text("Elimina", color = MatchColors.PrimaryRed)
|
||||
Text(stringResource(R.string.sheet_delete), color = MatchColors.PrimaryRed)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("Annulla", color = MatchColors.TextSecondary)
|
||||
Text(stringResource(R.string.action_cancel), color = MatchColors.TextSecondary)
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -444,6 +465,11 @@ private fun SheetOptionTile(
|
||||
private fun SelectMatchTile(match: Match, now: Instant, onClick: () -> Unit) {
|
||||
val scheduledInstant = parseApiInstant(match.scheduledAt)
|
||||
val isFuture = scheduledInstant?.isAfter(now) == true
|
||||
val badge = when {
|
||||
scheduledInstant == null -> stringResource(R.string.sheet_badge_draft)
|
||||
isFuture -> stringResource(R.string.sheet_badge_scheduled)
|
||||
else -> stringResource(R.string.sheet_badge_calendar)
|
||||
}
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -462,11 +488,7 @@ private fun SelectMatchTile(match: Match, now: Instant, onClick: () -> Unit) {
|
||||
}
|
||||
}
|
||||
Text(
|
||||
when {
|
||||
scheduledInstant == null -> "BOZZA"
|
||||
isFuture -> "PROGRAMMATA"
|
||||
else -> "IN CALENDARIO"
|
||||
},
|
||||
badge,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = if (isFuture) MatchColors.PrimaryRed else MatchColors.TextSecondary,
|
||||
modifier = Modifier
|
||||
@@ -576,7 +598,7 @@ fun ActiveSessionBanner(
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(
|
||||
"Riprendi diretta in corso",
|
||||
stringResource(R.string.sheet_resume_banner),
|
||||
color = MatchColors.PrimaryRed,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
@@ -610,16 +632,21 @@ fun MatchOutlinedField(
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun matchStatusLabel(match: Match): String {
|
||||
if (match.canResumeCamera) return "RIPRENDI"
|
||||
if (match.hasActiveSession) return "IN CORSO"
|
||||
if (match.canResumeCamera) return stringResource(R.string.match_status_resume)
|
||||
if (match.hasActiveSession) return stringResource(R.string.match_status_live)
|
||||
val at = parseApiInstant(match.scheduledAt)
|
||||
if (at != null && at.isScheduledFuture()) return "PROGRAMMATA"
|
||||
return "AVVIA"
|
||||
if (at != null && at.isScheduledFuture()) return stringResource(R.string.match_status_scheduled)
|
||||
return stringResource(R.string.match_status_start)
|
||||
}
|
||||
|
||||
fun formatMatchDate(instant: Instant): String =
|
||||
sheetDateFormat.format(instant.atZone(ZoneId.systemDefault()))
|
||||
@Composable
|
||||
fun formatMatchDate(instant: Instant): String {
|
||||
val formatter = sheetDateFormatter()
|
||||
return formatter.format(instant.atZone(ZoneId.systemDefault()))
|
||||
}
|
||||
|
||||
fun formatMatchDate(iso: String?): String? =
|
||||
@Composable
|
||||
fun formatMatchDateOrNull(iso: String?): String? =
|
||||
parseApiInstant(iso)?.let { formatMatchDate(it) }
|
||||
|
||||
+15
-8
@@ -72,6 +72,13 @@ fun MatchesScreen(
|
||||
val scope = rememberCoroutineScope()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val session by container.authRepository.sessionFlow.collectAsState(initial = null)
|
||||
val msgLoadError = stringResource(R.string.matches_msg_load_error)
|
||||
val msgResumeFailed = stringResource(R.string.matches_msg_resume_failed)
|
||||
val msgCreateFailed = stringResource(R.string.matches_msg_create_failed)
|
||||
val msgScheduledOk = stringResource(R.string.matches_msg_scheduled_ok)
|
||||
val msgScheduleError = stringResource(R.string.matches_msg_schedule_error)
|
||||
val msgDeleted = stringResource(R.string.matches_msg_deleted)
|
||||
val msgDeleteFailed = stringResource(R.string.matches_msg_delete_failed)
|
||||
|
||||
var loading by remember { mutableStateOf(true) }
|
||||
var refreshing by remember { mutableStateOf(false) }
|
||||
@@ -108,7 +115,7 @@ fun MatchesScreen(
|
||||
activeTeam = team
|
||||
matches = team?.let { container.matchRepository.fetchMatchesForTeam(it.id) }.orEmpty()
|
||||
}.onFailure {
|
||||
error = it.message ?: "Errore caricamento"
|
||||
error = it.message ?: msgLoadError
|
||||
}
|
||||
loading = false
|
||||
refreshing = false
|
||||
@@ -128,7 +135,7 @@ fun MatchesScreen(
|
||||
}.onSuccess { session ->
|
||||
onOpenBroadcast(session.id)
|
||||
}.onFailure {
|
||||
showMessage(it.message ?: "Impossibile riprendere la diretta")
|
||||
showMessage(it.message ?: msgResumeFailed)
|
||||
}
|
||||
actionLoading = false
|
||||
}
|
||||
@@ -365,7 +372,7 @@ fun MatchesScreen(
|
||||
openSetup(match)
|
||||
}
|
||||
.onFailure {
|
||||
showMessage(it.message ?: "Impossibile creare la partita")
|
||||
showMessage(it.message ?: msgCreateFailed)
|
||||
}
|
||||
actionLoading = false
|
||||
}
|
||||
@@ -393,10 +400,10 @@ fun MatchesScreen(
|
||||
)
|
||||
}.onSuccess { match ->
|
||||
reload()
|
||||
showMessage("Partita programmata — visibile sul sito")
|
||||
showMessage(msgScheduledOk)
|
||||
configureMatch = match
|
||||
}.onFailure {
|
||||
showMessage(it.message ?: "Errore creazione partita")
|
||||
showMessage(it.message ?: msgScheduleError)
|
||||
}
|
||||
actionLoading = false
|
||||
}
|
||||
@@ -454,10 +461,10 @@ fun MatchesScreen(
|
||||
runCatching { container.matchRepository.deleteMatch(match.id) }
|
||||
.onSuccess {
|
||||
reload()
|
||||
showMessage("Partita eliminata")
|
||||
showMessage(msgDeleted)
|
||||
}
|
||||
.onFailure {
|
||||
showMessage(it.message ?: "Impossibile eliminare")
|
||||
showMessage(it.message ?: msgDeleteFailed)
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -513,7 +520,7 @@ private fun MatchListCard(
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
formatMatchDate(match.scheduledAt)?.let {
|
||||
formatMatchDateOrNull(match.scheduledAt)?.let {
|
||||
Text(it, style = MaterialTheme.typography.bodyMedium)
|
||||
}
|
||||
match.location?.takeIf { it.isNotBlank() }?.let {
|
||||
|
||||
+49
-28
@@ -26,7 +26,9 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.core.normalizeHexColor
|
||||
import com.matchlivetv.match_live_tv.data.AppContainer
|
||||
import com.matchlivetv.match_live_tv.data.api.ScoringRulesBody
|
||||
@@ -37,7 +39,7 @@ import com.matchlivetv.match_live_tv.streaming.overlay.OverlayKind
|
||||
import com.matchlivetv.match_live_tv.ui.components.MatchPrimaryButton
|
||||
import com.matchlivetv.match_live_tv.ui.components.MatchSecondaryButton
|
||||
import com.matchlivetv.match_live_tv.ui.matches.MatchOutlinedField
|
||||
import com.matchlivetv.match_live_tv.ui.matches.formatMatchDate
|
||||
import com.matchlivetv.match_live_tv.ui.matches.formatMatchDateOrNull
|
||||
import com.matchlivetv.match_live_tv.ui.theme.MatchColors
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -181,16 +183,23 @@ fun StepMatchScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val opponentNameRequiredError = stringResource(R.string.wizard_error_opponent_name_required)
|
||||
val pointsPerSetRequiredError = stringResource(R.string.wizard_error_points_per_set_required)
|
||||
val tiebreakPointsRequiredError = stringResource(R.string.wizard_error_tiebreak_points_required)
|
||||
val periodDurationRequiredError = stringResource(R.string.wizard_error_period_duration_required)
|
||||
val overtimeDurationRequiredError = stringResource(R.string.wizard_error_overtime_duration_required)
|
||||
val saveGenericError = stringResource(R.string.wizard_error_save_generic)
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 20.dp, vertical = 12.dp),
|
||||
) {
|
||||
Text("Dettagli partita", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.wizard_match_details_title), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(20.dp))
|
||||
|
||||
TeamBrandingRow(
|
||||
sectionLabel = "Squadra di casa",
|
||||
sectionLabel = stringResource(R.string.wizard_match_home_team_label),
|
||||
teamName = match.teamName,
|
||||
nameEditable = false,
|
||||
onTeamNameChange = {},
|
||||
@@ -206,7 +215,7 @@ fun StepMatchScreen(
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
TeamBrandingRow(
|
||||
sectionLabel = "Squadra avversaria",
|
||||
sectionLabel = stringResource(R.string.wizard_match_away_team_label),
|
||||
teamName = opponent,
|
||||
nameEditable = true,
|
||||
onTeamNameChange = { opponent = it },
|
||||
@@ -221,15 +230,19 @@ fun StepMatchScreen(
|
||||
onClearLogo = { opponentLogoUri = null },
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
MatchOutlinedField(value = location, onValueChange = { location = it }, label = "Luogo")
|
||||
MatchOutlinedField(
|
||||
value = location,
|
||||
onValueChange = { location = it },
|
||||
label = stringResource(R.string.wizard_match_location_label),
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
MatchOutlinedField(
|
||||
value = campionato,
|
||||
onValueChange = { campionato = it },
|
||||
label = "Campionato (facoltativo)",
|
||||
label = stringResource(R.string.wizard_match_category_label),
|
||||
)
|
||||
Text(
|
||||
"Es. Serie C, torneo estivo — lo useremo in descrizione e overlay.",
|
||||
stringResource(R.string.wizard_match_category_hint),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
@@ -238,8 +251,8 @@ fun StepMatchScreen(
|
||||
if (isScheduledMatch) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
WizardReadOnlyField(
|
||||
label = "Programmata per",
|
||||
value = formatMatchDate(match.scheduledAt) ?: "—",
|
||||
label = stringResource(R.string.wizard_match_scheduled_label),
|
||||
value = formatMatchDateOrNull(match.scheduledAt) ?: "—",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -250,7 +263,7 @@ fun StepMatchScreen(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text("Overlay video personalizzato", modifier = Modifier.weight(1f))
|
||||
Text(stringResource(R.string.wizard_match_custom_overlay_label), modifier = Modifier.weight(1f))
|
||||
Switch(checked = customOverlay, onCheckedChange = { customOverlay = it })
|
||||
}
|
||||
if (customOverlay) {
|
||||
@@ -282,17 +295,17 @@ fun StepMatchScreen(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text("Regole punteggio personalizzate")
|
||||
Text(stringResource(R.string.wizard_match_custom_rules_label))
|
||||
Text(
|
||||
when {
|
||||
!customRules && boardType in setOf("basket", "timed") ->
|
||||
"Regole standard dello sport selezionato."
|
||||
stringResource(R.string.wizard_match_rules_standard_sport)
|
||||
customRules && boardType in setOf("basket", "timed") ->
|
||||
"Torneo non standard: tempi e periodi personalizzati."
|
||||
stringResource(R.string.wizard_match_rules_custom_timed)
|
||||
customRules ->
|
||||
"Torneo non standard: imposta set e punteggi."
|
||||
stringResource(R.string.wizard_match_rules_custom_sets)
|
||||
else ->
|
||||
"Standard FIPAV: 3 set per vincere, set a 25, tie-break a 15."
|
||||
stringResource(R.string.wizard_match_rules_standard_sets)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
@@ -304,7 +317,11 @@ fun StepMatchScreen(
|
||||
if (customRules && boardType in setOf("basket", "timed")) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(
|
||||
if (boardType == "basket") "Quarti" else "Tempi",
|
||||
if (boardType == "basket") {
|
||||
stringResource(R.string.wizard_match_periods_basket_label)
|
||||
} else {
|
||||
stringResource(R.string.wizard_match_periods_timed_label)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
@@ -333,7 +350,11 @@ fun StepMatchScreen(
|
||||
periodDurationText = text.filter { it.isDigit() }.take(3)
|
||||
periodDurationText.toIntOrNull()?.let { periodDurationMins = it.coerceIn(1, 120) }
|
||||
},
|
||||
label = if (boardType == "basket") "Minuti per quarto" else "Minuti per tempo",
|
||||
label = if (boardType == "basket") {
|
||||
stringResource(R.string.wizard_match_minutes_per_period_basket)
|
||||
} else {
|
||||
stringResource(R.string.wizard_match_minutes_per_period_timed)
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
MatchOutlinedField(
|
||||
@@ -342,13 +363,13 @@ fun StepMatchScreen(
|
||||
overtimeDurationText = text.filter { it.isDigit() }.take(3)
|
||||
overtimeDurationText.toIntOrNull()?.let { overtimeDurationMins = it.coerceIn(1, 60) }
|
||||
},
|
||||
label = "Minuti supplementari",
|
||||
label = stringResource(R.string.wizard_match_overtime_minutes_label),
|
||||
)
|
||||
}
|
||||
|
||||
if (customRules && boardType in setOf("volley", "racket")) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text("Set da vincere la partita", style = MaterialTheme.typography.bodyMedium)
|
||||
Text(stringResource(R.string.wizard_match_sets_to_win_label), style = MaterialTheme.typography.bodyMedium)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
listOf(2, 3).forEach { value ->
|
||||
@@ -375,7 +396,7 @@ fun StepMatchScreen(
|
||||
pointsPerSetText = text.filter { it.isDigit() }.take(2)
|
||||
pointsPerSetText.toIntOrNull()?.let { pointsPerSet = it.coerceIn(1, 99) }
|
||||
},
|
||||
label = "Punti per vincere un set",
|
||||
label = stringResource(R.string.wizard_match_points_per_set_label),
|
||||
)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
MatchOutlinedField(
|
||||
@@ -384,28 +405,28 @@ fun StepMatchScreen(
|
||||
pointsDecidingSetText = text.filter { it.isDigit() }.take(2)
|
||||
pointsDecidingSetText.toIntOrNull()?.let { pointsDecidingSet = it.coerceIn(1, 99) }
|
||||
},
|
||||
label = "Punti tie-break (ultimo set)",
|
||||
label = stringResource(R.string.wizard_match_tiebreak_points_label),
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(32.dp))
|
||||
MatchPrimaryButton(
|
||||
label = "AVANTI >",
|
||||
label = stringResource(R.string.wizard_action_next),
|
||||
loading = saving,
|
||||
onClick = {
|
||||
if (opponent.isBlank()) {
|
||||
onError("Inserisci il nome avversario")
|
||||
onError(opponentNameRequiredError)
|
||||
return@MatchPrimaryButton
|
||||
}
|
||||
if (customRules && boardType in setOf("volley", "racket")) {
|
||||
val perSet = pointsPerSetText.toIntOrNull()
|
||||
val deciding = pointsDecidingSetText.toIntOrNull()
|
||||
if (perSet == null || perSet < 1) {
|
||||
onError("Inserisci i punti per vincere un set")
|
||||
onError(pointsPerSetRequiredError)
|
||||
return@MatchPrimaryButton
|
||||
}
|
||||
if (deciding == null || deciding < 1) {
|
||||
onError("Inserisci i punti del tie-break")
|
||||
onError(tiebreakPointsRequiredError)
|
||||
return@MatchPrimaryButton
|
||||
}
|
||||
pointsPerSet = perSet
|
||||
@@ -415,11 +436,11 @@ fun StepMatchScreen(
|
||||
val periodMins = periodDurationText.toIntOrNull()
|
||||
val overtimeMins = overtimeDurationText.toIntOrNull()
|
||||
if (periodMins == null || periodMins < 1) {
|
||||
onError("Inserisci la durata del periodo in minuti")
|
||||
onError(periodDurationRequiredError)
|
||||
return@MatchPrimaryButton
|
||||
}
|
||||
if (overtimeMins == null || overtimeMins < 1) {
|
||||
onError("Inserisci la durata dei supplementari in minuti")
|
||||
onError(overtimeDurationRequiredError)
|
||||
return@MatchPrimaryButton
|
||||
}
|
||||
periodDurationMins = periodMins
|
||||
@@ -484,7 +505,7 @@ fun StepMatchScreen(
|
||||
container.wizardSession.match = updated
|
||||
onNext()
|
||||
}.onFailure {
|
||||
onError(it.message ?: "Errore nel salvataggio")
|
||||
onError(it.message ?: saveGenericError)
|
||||
}
|
||||
saving = false
|
||||
}
|
||||
|
||||
+40
-23
@@ -26,8 +26,10 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.data.AppContainer
|
||||
import com.matchlivetv.match_live_tv.domain.Match
|
||||
import com.matchlivetv.match_live_tv.domain.StreamSession
|
||||
@@ -109,42 +111,52 @@ fun StepNetworkTestScreen(
|
||||
|
||||
val shareUrl = currentSession.watchShareUrl()
|
||||
|
||||
val shareSubject = stringResource(R.string.wizard_network_share_subject, match.teamName, match.opponentName)
|
||||
val shareChooserLiveTitle = stringResource(R.string.wizard_share_chooser_live)
|
||||
val shareChooserRegiaTitle = stringResource(R.string.wizard_share_chooser_regia)
|
||||
val regiaLinkError = stringResource(R.string.wizard_error_regia_link)
|
||||
val startLiveError = stringResource(R.string.wizard_error_start_live)
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 20.dp, vertical = 12.dp),
|
||||
) {
|
||||
Text("Test rete", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.wizard_network_test_title), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
"Verifica che la connessione regga l'upload della diretta.",
|
||||
stringResource(R.string.wizard_network_test_subtitle),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(Modifier.height(24.dp))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
MetricCard(
|
||||
label = "Download",
|
||||
label = stringResource(R.string.wizard_network_download_label),
|
||||
value = if (testing) "..." else "${"%.1f".format(downloadMbps)} Mbps",
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
MetricCard(
|
||||
label = "Upload",
|
||||
label = stringResource(R.string.wizard_network_upload_label),
|
||||
value = if (testing) "..." else "${"%.1f".format(uploadMbps)} Mbps",
|
||||
highlight = ready,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
MetricCard(
|
||||
label = "Latenza",
|
||||
label = stringResource(R.string.wizard_network_latency_label),
|
||||
value = if (testing) "..." else "$latencyMs ms",
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(12.dp))
|
||||
MetricCard(label = "Tipo rete", value = networkType, modifier = Modifier.fillMaxWidth())
|
||||
MetricCard(
|
||||
label = stringResource(R.string.wizard_network_type_label),
|
||||
value = networkType,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
if (testCompleted && ready) {
|
||||
Spacer(Modifier.height(20.dp))
|
||||
Text(
|
||||
"PRONTO PER ANDARE IN DIRETTA",
|
||||
stringResource(R.string.wizard_network_ready_label),
|
||||
color = MatchColors.SuccessGreen,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
@@ -153,7 +165,7 @@ fun StepNetworkTestScreen(
|
||||
selectedQualityLabel?.let { quality ->
|
||||
Spacer(Modifier.height(12.dp))
|
||||
WizardReadOnlyField(
|
||||
label = "Qualità streaming (automatica)",
|
||||
label = stringResource(R.string.wizard_network_quality_label),
|
||||
value = quality,
|
||||
)
|
||||
}
|
||||
@@ -161,30 +173,31 @@ fun StepNetworkTestScreen(
|
||||
if (testCompleted && shareUrl != null) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
WizardReadOnlyField(
|
||||
label = if (currentSession.platform == "youtube") "Link YouTube" else "Link diretta",
|
||||
label = if (currentSession.platform == "youtube") {
|
||||
stringResource(R.string.wizard_network_link_youtube_label)
|
||||
} else {
|
||||
stringResource(R.string.wizard_network_link_live_label)
|
||||
},
|
||||
value = shareUrl,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
MatchSecondaryButton(
|
||||
label = "COPIA",
|
||||
label = stringResource(R.string.wizard_action_copy),
|
||||
onClick = { copyToClipboard(context, shareUrl) },
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
MatchSecondaryButton(
|
||||
label = "CONDIVIDI",
|
||||
label = stringResource(R.string.wizard_action_share),
|
||||
onClick = {
|
||||
context.startActivity(
|
||||
Intent.createChooser(
|
||||
Intent(Intent.ACTION_SEND).apply {
|
||||
type = "text/plain"
|
||||
putExtra(Intent.EXTRA_TEXT, shareUrl)
|
||||
putExtra(
|
||||
Intent.EXTRA_SUBJECT,
|
||||
"Diretta — ${match.teamName} vs ${match.opponentName}",
|
||||
)
|
||||
putExtra(Intent.EXTRA_SUBJECT, shareSubject)
|
||||
},
|
||||
"Condividi diretta",
|
||||
shareChooserLiveTitle,
|
||||
),
|
||||
)
|
||||
},
|
||||
@@ -193,7 +206,7 @@ fun StepNetworkTestScreen(
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
MatchSecondaryButton(
|
||||
label = "CONDIVIDI LINK REGIA",
|
||||
label = stringResource(R.string.wizard_action_share_regia_link),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
runCatching { container.sessionRepository.createRegiaLink(currentSession.id) }
|
||||
@@ -204,11 +217,11 @@ fun StepNetworkTestScreen(
|
||||
type = "text/plain"
|
||||
putExtra(Intent.EXTRA_TEXT, url)
|
||||
},
|
||||
"Condividi regia",
|
||||
shareChooserRegiaTitle,
|
||||
),
|
||||
)
|
||||
}
|
||||
.onFailure { onError(it.message ?: "Errore link regia") }
|
||||
.onFailure { onError(it.message ?: regiaLinkError) }
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -216,7 +229,11 @@ fun StepNetworkTestScreen(
|
||||
if (!testCompleted) {
|
||||
Spacer(Modifier.height(24.dp))
|
||||
MatchSecondaryButton(
|
||||
label = if (testing) "TEST IN CORSO..." else "AVVIA TEST RETE",
|
||||
label = if (testing) {
|
||||
stringResource(R.string.wizard_network_test_running_label)
|
||||
} else {
|
||||
stringResource(R.string.wizard_network_test_start_label)
|
||||
},
|
||||
enabled = !testing,
|
||||
onClick = { runTest() },
|
||||
)
|
||||
@@ -224,14 +241,14 @@ fun StepNetworkTestScreen(
|
||||
Spacer(Modifier.height(32.dp))
|
||||
Row {
|
||||
MatchSecondaryButton(
|
||||
label = "Indietro",
|
||||
label = stringResource(R.string.wizard_action_back),
|
||||
onClick = onBack,
|
||||
enabled = !starting,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Spacer(Modifier.width(12.dp))
|
||||
MatchPrimaryButton(
|
||||
label = "INIZIA >",
|
||||
label = stringResource(R.string.wizard_action_start),
|
||||
loading = starting,
|
||||
enabled = ready,
|
||||
onClick = {
|
||||
@@ -242,7 +259,7 @@ fun StepNetworkTestScreen(
|
||||
container.wizardSession.setSession(started, match)
|
||||
onStartLive(started)
|
||||
}
|
||||
.onFailure { onError(it.message ?: "Errore avvio diretta") }
|
||||
.onFailure { onError(it.message ?: startLiveError) }
|
||||
starting = false
|
||||
}
|
||||
},
|
||||
|
||||
+22
-17
@@ -20,7 +20,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.data.AppContainer
|
||||
import com.matchlivetv.match_live_tv.domain.Match
|
||||
import com.matchlivetv.match_live_tv.domain.Team
|
||||
@@ -57,12 +59,15 @@ fun StepTransmissionScreen(
|
||||
|
||||
val loadedTeam = team
|
||||
val youtubeReady = loadedTeam?.isYoutubeReady == true
|
||||
val youtubeActivatingLabel = stringResource(R.string.wizard_transmission_youtube_activating)
|
||||
val youtubeSubtitle = when {
|
||||
loadedTeam == null -> "Canale in attivazione"
|
||||
!loadedTeam.canUseYoutube -> "Premium Light o Full"
|
||||
!loadedTeam.isYoutubeReady -> "Canale in attivazione"
|
||||
loadedTeam == null -> youtubeActivatingLabel
|
||||
!loadedTeam.canUseYoutube -> stringResource(R.string.wizard_transmission_youtube_premium_required)
|
||||
!loadedTeam.isYoutubeReady -> youtubeActivatingLabel
|
||||
else -> loadedTeam.youtubeDestinationLabel
|
||||
}
|
||||
val youtubeUnavailableError = stringResource(R.string.wizard_error_youtube_unavailable)
|
||||
val sessionCreateError = stringResource(R.string.wizard_error_session_create)
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
@@ -71,7 +76,7 @@ fun StepTransmissionScreen(
|
||||
) {
|
||||
team?.planName?.let { plan ->
|
||||
Text(
|
||||
"Piano $plan",
|
||||
stringResource(R.string.wizard_transmission_plan_label, plan),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
modifier = Modifier
|
||||
@@ -79,11 +84,11 @@ fun StepTransmissionScreen(
|
||||
.padding(bottom = 12.dp),
|
||||
)
|
||||
}
|
||||
Text("Piattaforma", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.wizard_transmission_platform_title), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
WizardPlatformCard(
|
||||
title = "Match Live TV",
|
||||
subtitle = "Diretta sul nostro sito (incluso)",
|
||||
subtitle = stringResource(R.string.wizard_transmission_platform_site_subtitle),
|
||||
selected = platform == "matchlivetv",
|
||||
onClick = { platform = "matchlivetv" },
|
||||
)
|
||||
@@ -93,27 +98,27 @@ fun StepTransmissionScreen(
|
||||
subtitle = youtubeSubtitle,
|
||||
selected = platform == "youtube",
|
||||
enabled = youtubeReady,
|
||||
badge = if (team?.canUseYoutube != true) "Premium" else null,
|
||||
badge = if (team?.canUseYoutube != true) stringResource(R.string.wizard_transmission_youtube_badge) else null,
|
||||
onClick = {
|
||||
if (youtubeReady) {
|
||||
platform = "youtube"
|
||||
} else {
|
||||
onError("YouTube non disponibile per questa squadra")
|
||||
onError(youtubeUnavailableError)
|
||||
}
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(24.dp))
|
||||
Text("Visibilità", style = MaterialTheme.typography.headlineMedium)
|
||||
Text(stringResource(R.string.wizard_transmission_visibility_title), style = MaterialTheme.typography.headlineMedium)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Row(horizontalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(8.dp)) {
|
||||
WizardChoiceButton(
|
||||
label = "PUBBLICO",
|
||||
label = stringResource(R.string.wizard_transmission_public_label),
|
||||
selected = privacy == "public",
|
||||
onClick = { privacy = "public" },
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
WizardChoiceButton(
|
||||
label = "NON IN ELENCO",
|
||||
label = stringResource(R.string.wizard_transmission_unlisted_label),
|
||||
selected = privacy == "unlisted",
|
||||
onClick = { privacy = "unlisted" },
|
||||
modifier = Modifier.weight(1f),
|
||||
@@ -122,15 +127,15 @@ fun StepTransmissionScreen(
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
if (privacy == "public") {
|
||||
"Compare nell'elenco dirette su MatchLiveTV.it, nelle ricerche e sul canale YouTube (se selezionato)."
|
||||
stringResource(R.string.wizard_transmission_public_desc)
|
||||
} else {
|
||||
"Non compare negli elenchi pubblici né nelle ricerche. Solo chi ha il link può guardare."
|
||||
stringResource(R.string.wizard_transmission_unlisted_desc)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
Text(
|
||||
"La partita resta sempre visibile nel backend della squadra per tutta la durata dell'abbonamento.",
|
||||
stringResource(R.string.wizard_transmission_backend_note),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
modifier = Modifier.padding(top = 6.dp),
|
||||
@@ -138,13 +143,13 @@ fun StepTransmissionScreen(
|
||||
Spacer(Modifier.height(32.dp))
|
||||
Row {
|
||||
MatchSecondaryButton(
|
||||
label = "Indietro",
|
||||
label = stringResource(R.string.wizard_action_back),
|
||||
onClick = onBack,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Spacer(Modifier.width(12.dp))
|
||||
MatchPrimaryButton(
|
||||
label = "AVANTI >",
|
||||
label = stringResource(R.string.wizard_action_next),
|
||||
loading = creating,
|
||||
onClick = {
|
||||
creating = true
|
||||
@@ -160,7 +165,7 @@ fun StepTransmissionScreen(
|
||||
container.wizardSession.setSession(session, match)
|
||||
onNext()
|
||||
}.onFailure {
|
||||
onError(it.message ?: "Errore creazione sessione")
|
||||
onError(it.message ?: sessionCreateError)
|
||||
}
|
||||
creating = false
|
||||
}
|
||||
|
||||
+29
-16
@@ -39,9 +39,11 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.core.parseColorHex
|
||||
import com.matchlivetv.match_live_tv.core.placeholderTeamColor
|
||||
import com.matchlivetv.match_live_tv.core.resolveMediaUrl
|
||||
@@ -71,6 +73,8 @@ fun TeamBrandingRow(
|
||||
val placeholderColor = remember(placeholderColorSeed) { placeholderTeamColor(placeholderColorSeed) }
|
||||
val displayColorHex = primaryColorHex.ifBlank { placeholderColor }
|
||||
val displayColor = Color(parseColorHex(displayColorHex, 0xFFE53935.toInt()))
|
||||
val teamFallbackName = stringResource(R.string.wizard_branding_team_fallback_name)
|
||||
val opponentNamePlaceholder = stringResource(R.string.wizard_branding_opponent_name_placeholder)
|
||||
|
||||
var menuExpanded by remember { mutableStateOf(false) }
|
||||
var showCustomize by remember { mutableStateOf(false) }
|
||||
@@ -99,7 +103,7 @@ fun TeamBrandingRow(
|
||||
)
|
||||
ColorAccentBar(color = displayColor, height = 36.dp)
|
||||
Text(
|
||||
text = teamName.ifBlank { "Squadra" },
|
||||
text = teamName.ifBlank { teamFallbackName },
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
@@ -111,12 +115,12 @@ fun TeamBrandingRow(
|
||||
InlineTeamNameField(
|
||||
value = teamName,
|
||||
onValueChange = onTeamNameChange,
|
||||
placeholder = "Nome avversario",
|
||||
placeholder = opponentNamePlaceholder,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = teamName.ifBlank { "Squadra" },
|
||||
text = teamName.ifBlank { teamFallbackName },
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
@@ -129,7 +133,7 @@ fun TeamBrandingRow(
|
||||
IconButton(onClick = { menuExpanded = true }) {
|
||||
Icon(
|
||||
Icons.Default.MoreVert,
|
||||
contentDescription = "Modifica squadra",
|
||||
contentDescription = stringResource(R.string.wizard_branding_edit_team_cd),
|
||||
tint = MatchColors.TextSecondary,
|
||||
)
|
||||
}
|
||||
@@ -138,7 +142,7 @@ fun TeamBrandingRow(
|
||||
onDismissRequest = { menuExpanded = false },
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text("Personalizza") },
|
||||
text = { Text(stringResource(R.string.wizard_branding_customize_title)) },
|
||||
onClick = {
|
||||
menuExpanded = false
|
||||
showCustomize = true
|
||||
@@ -203,7 +207,7 @@ private fun TeamBrandingCustomizeSheet(
|
||||
.padding(horizontal = 20.dp)
|
||||
.padding(bottom = 32.dp),
|
||||
) {
|
||||
Text("Personalizza", style = MaterialTheme.typography.headlineSmall)
|
||||
Text(stringResource(R.string.wizard_branding_customize_title), style = MaterialTheme.typography.headlineSmall)
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
@@ -212,25 +216,30 @@ private fun TeamBrandingCustomizeSheet(
|
||||
Spacer(Modifier.height(20.dp))
|
||||
|
||||
if (nameEditable) {
|
||||
Text("Nome squadra", style = MaterialTheme.typography.labelLarge)
|
||||
Text(stringResource(R.string.wizard_branding_team_name_label), style = MaterialTheme.typography.labelLarge)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
OutlinedTextField(
|
||||
value = draftName,
|
||||
onValueChange = { draftName = it },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
placeholder = { Text("Nome avversario", color = MatchColors.TextSecondary) },
|
||||
placeholder = {
|
||||
Text(
|
||||
stringResource(R.string.wizard_branding_opponent_name_placeholder),
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
},
|
||||
colors = outlinedFieldColors(),
|
||||
)
|
||||
Spacer(Modifier.height(20.dp))
|
||||
} else {
|
||||
Text("Nome squadra", style = MaterialTheme.typography.labelLarge)
|
||||
Text(stringResource(R.string.wizard_branding_team_name_label), style = MaterialTheme.typography.labelLarge)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Text(teamName, style = MaterialTheme.typography.titleMedium)
|
||||
Spacer(Modifier.height(20.dp))
|
||||
}
|
||||
|
||||
Text("Logo", style = MaterialTheme.typography.labelLarge)
|
||||
Text(stringResource(R.string.wizard_branding_logo_label), style = MaterialTheme.typography.labelLarge)
|
||||
Spacer(Modifier.height(10.dp))
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
@@ -242,15 +251,15 @@ private fun TeamBrandingCustomizeSheet(
|
||||
size = 72.dp,
|
||||
)
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
MatchSecondaryButton(label = "CARICA LOGO", onClick = onPickLogo)
|
||||
MatchSecondaryButton(label = stringResource(R.string.wizard_branding_upload_logo), onClick = onPickLogo)
|
||||
if (hasLogo) {
|
||||
MatchSecondaryButton(label = "RIMUOVI", onClick = onClearLogo)
|
||||
MatchSecondaryButton(label = stringResource(R.string.wizard_branding_remove_logo), onClick = onClearLogo)
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(20.dp))
|
||||
|
||||
Text("Colore squadra", style = MaterialTheme.typography.labelLarge)
|
||||
Text(stringResource(R.string.wizard_branding_color_label), style = MaterialTheme.typography.labelLarge)
|
||||
Spacer(Modifier.height(12.dp))
|
||||
TeamColorPickerPanel(
|
||||
initialColorHex = pickerInitialColor,
|
||||
@@ -259,11 +268,11 @@ private fun TeamBrandingCustomizeSheet(
|
||||
Spacer(Modifier.height(24.dp))
|
||||
|
||||
MatchPrimaryButton(
|
||||
label = "SALVA",
|
||||
label = stringResource(R.string.wizard_branding_save),
|
||||
onClick = { onConfirm(draftName.trim(), draftColor.trim()) },
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
MatchSecondaryButton(label = "ANNULLA", onClick = onDismiss)
|
||||
MatchSecondaryButton(label = stringResource(R.string.wizard_branding_cancel), onClick = onDismiss)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +304,11 @@ private fun TeamLogoPreview(
|
||||
modifier = Modifier.size(size),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
else -> Text("Nessun logo", style = MaterialTheme.typography.labelMedium, color = MatchColors.TextSecondary)
|
||||
else -> Text(
|
||||
stringResource(R.string.wizard_branding_no_logo),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -26,6 +26,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
@@ -33,6 +34,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.core.hsvToHex
|
||||
import com.matchlivetv.match_live_tv.core.parseColorHex
|
||||
import com.matchlivetv.match_live_tv.ui.theme.MatchColors
|
||||
@@ -152,7 +154,7 @@ private fun HueSlider(
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
Text(
|
||||
"Tonalità",
|
||||
stringResource(R.string.wizard_color_hue),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MatchColors.TextSecondary,
|
||||
)
|
||||
|
||||
+8
-8
@@ -29,17 +29,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.ui.components.MatchPrimaryButton
|
||||
import com.matchlivetv.match_live_tv.ui.components.MatchSecondaryButton
|
||||
import com.matchlivetv.match_live_tv.ui.theme.MatchColors
|
||||
|
||||
private val stepTitles = listOf(
|
||||
"01 · Partita",
|
||||
"02 · Trasmissione",
|
||||
"03 · Test rete",
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun WizardStepIndicator(currentStep: Int, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
@@ -62,8 +58,12 @@ fun WizardStepIndicator(currentStep: Int, modifier: Modifier = Modifier) {
|
||||
}
|
||||
}
|
||||
|
||||
fun wizardStepTitle(step: Int): String =
|
||||
stepTitles[(step.coerceIn(1, 3) - 1)]
|
||||
@Composable
|
||||
fun wizardStepTitle(step: Int): String = when (step.coerceIn(1, 3)) {
|
||||
1 -> stringResource(R.string.wizard_step_title_match)
|
||||
2 -> stringResource(R.string.wizard_step_title_transmission)
|
||||
else -> stringResource(R.string.wizard_step_title_network)
|
||||
}
|
||||
|
||||
private fun sportWizardIcon(sportKey: String, boardType: String): ImageVector = when {
|
||||
sportKey.contains("volley") || boardType == "volley" || boardType == "racket" ->
|
||||
|
||||
+9
-3
@@ -26,7 +26,9 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.data.AppContainer
|
||||
import com.matchlivetv.match_live_tv.domain.Match
|
||||
import com.matchlivetv.match_live_tv.domain.StreamSession
|
||||
@@ -74,7 +76,11 @@ fun WizardShellScreen(
|
||||
title = { Text(wizardStepTitle(currentStep)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onClose) {
|
||||
Icon(Icons.Default.Close, contentDescription = "Chiudi", tint = Color.White)
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.common_close),
|
||||
tint = Color.White,
|
||||
)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
@@ -104,7 +110,7 @@ fun WizardShellScreen(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
)
|
||||
match == null -> Text(
|
||||
"Partita non trovata",
|
||||
stringResource(R.string.wizard_match_not_found),
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
@@ -128,7 +134,7 @@ fun WizardShellScreen(
|
||||
val session = container.wizardSession.session
|
||||
if (session == null) {
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text("Completa lo step Trasmissione")
|
||||
Text(stringResource(R.string.wizard_complete_transmission_step))
|
||||
}
|
||||
} else {
|
||||
StepNetworkTestScreen(
|
||||
|
||||
@@ -47,4 +47,198 @@
|
||||
<string name="streaming_notification_reconnecting">Erneute Verbindung…</string>
|
||||
<string name="streaming_notification_error">Streaming-Fehler</string>
|
||||
<string name="streaming_notification_stop">Beenden</string>
|
||||
|
||||
<string name="common_close">Schließen</string>
|
||||
<string name="common_error_generic">Fehler</string>
|
||||
|
||||
<string name="wizard_step_title_match">01 · Spiel</string>
|
||||
<string name="wizard_step_title_transmission">02 · Übertragung</string>
|
||||
<string name="wizard_step_title_network">03 · Netzwerktest</string>
|
||||
<string name="wizard_match_not_found">Spiel nicht gefunden</string>
|
||||
<string name="wizard_complete_transmission_step">Schließe den Schritt Übertragung ab</string>
|
||||
<string name="wizard_action_next">WEITER ></string>
|
||||
<string name="wizard_action_back">Zurück</string>
|
||||
<string name="wizard_action_start">STARTEN ></string>
|
||||
<string name="wizard_match_details_title">Spieldetails</string>
|
||||
<string name="wizard_match_home_team_label">Heimteam</string>
|
||||
<string name="wizard_match_away_team_label">Gastteam</string>
|
||||
<string name="wizard_match_location_label">Ort</string>
|
||||
<string name="wizard_match_category_label">Liga (optional)</string>
|
||||
<string name="wizard_match_category_hint">Z. B. Serie C, Sommerturnier — wird in Beschreibung und Overlay verwendet.</string>
|
||||
<string name="wizard_match_scheduled_label">Geplant für</string>
|
||||
<string name="wizard_match_custom_overlay_label">Individuelles Video-Overlay</string>
|
||||
<string name="wizard_match_custom_rules_label">Individuelle Punkteregeln</string>
|
||||
<string name="wizard_match_rules_standard_sport">Standardregeln der gewählten Sportart.</string>
|
||||
<string name="wizard_match_rules_custom_timed">Nicht standardmäßiges Turnier: individuelle Zeiten und Perioden.</string>
|
||||
<string name="wizard_match_rules_custom_sets">Nicht standardmäßiges Turnier: Sätze und Punkte festlegen.</string>
|
||||
<string name="wizard_match_rules_standard_sets">FIVB-Standard: 3 Gewinnsätze, Sätze bis 25, Tie-Break bis 15.</string>
|
||||
<string name="wizard_match_periods_basket_label">Viertel</string>
|
||||
<string name="wizard_match_periods_timed_label">Halbzeiten</string>
|
||||
<string name="wizard_match_minutes_per_period_basket">Minuten pro Viertel</string>
|
||||
<string name="wizard_match_minutes_per_period_timed">Minuten pro Halbzeit</string>
|
||||
<string name="wizard_match_overtime_minutes_label">Verlängerungsminuten</string>
|
||||
<string name="wizard_match_sets_to_win_label">Sätze zum Spielgewinn</string>
|
||||
<string name="wizard_match_points_per_set_label">Punkte zum Satzgewinn</string>
|
||||
<string name="wizard_match_tiebreak_points_label">Tie-Break-Punkte (letzter Satz)</string>
|
||||
<string name="wizard_error_opponent_name_required">Gib den Namen des Gegners ein</string>
|
||||
<string name="wizard_error_points_per_set_required">Gib die Punkte zum Satzgewinn ein</string>
|
||||
<string name="wizard_error_tiebreak_points_required">Gib die Tie-Break-Punkte ein</string>
|
||||
<string name="wizard_error_period_duration_required">Gib die Dauer der Periode in Minuten ein</string>
|
||||
<string name="wizard_error_overtime_duration_required">Gib die Dauer der Verlängerung in Minuten ein</string>
|
||||
<string name="wizard_error_save_generic">Fehler beim Speichern</string>
|
||||
<string name="wizard_transmission_plan_label">Tarif %1$s</string>
|
||||
<string name="wizard_transmission_platform_title">Plattform</string>
|
||||
<string name="wizard_transmission_platform_site_subtitle">Live auf unserer Website (inklusive)</string>
|
||||
<string name="wizard_transmission_youtube_activating">Kanal wird aktiviert</string>
|
||||
<string name="wizard_transmission_youtube_premium_required">Premium Light oder Full</string>
|
||||
<string name="wizard_transmission_youtube_badge">Premium</string>
|
||||
<string name="wizard_error_youtube_unavailable">YouTube für dieses Team nicht verfügbar</string>
|
||||
<string name="wizard_transmission_visibility_title">Sichtbarkeit</string>
|
||||
<string name="wizard_transmission_public_label">ÖFFENTLICH</string>
|
||||
<string name="wizard_transmission_unlisted_label">NICHT GELISTET</string>
|
||||
<string name="wizard_transmission_public_desc">Erscheint in der Live-Liste auf MatchLiveTV.it, in der Suche und im YouTube-Kanal (falls ausgewählt).</string>
|
||||
<string name="wizard_transmission_unlisted_desc">Erscheint nicht in öffentlichen Listen oder in der Suche. Nur mit dem Link kann zugesehen werden.</string>
|
||||
<string name="wizard_transmission_backend_note">Das Spiel bleibt für die gesamte Abo-Dauer im Team-Backend sichtbar.</string>
|
||||
<string name="wizard_error_session_create">Fehler beim Erstellen der Sitzung</string>
|
||||
<string name="wizard_network_test_title">Netzwerktest</string>
|
||||
<string name="wizard_network_test_subtitle">Prüfe, ob deine Verbindung den Live-Upload verkraftet.</string>
|
||||
<string name="wizard_network_download_label">Download</string>
|
||||
<string name="wizard_network_upload_label">Upload</string>
|
||||
<string name="wizard_network_latency_label">Latenz</string>
|
||||
<string name="wizard_network_type_label">Netzwerktyp</string>
|
||||
<string name="wizard_network_ready_label">BEREIT FÜR DEN LIVE-START</string>
|
||||
<string name="wizard_network_quality_label">Streaming-Qualität (automatisch)</string>
|
||||
<string name="wizard_network_link_youtube_label">YouTube-Link</string>
|
||||
<string name="wizard_network_link_live_label">Live-Link</string>
|
||||
<string name="wizard_action_copy">KOPIEREN</string>
|
||||
<string name="wizard_action_share">TEILEN</string>
|
||||
<string name="wizard_network_share_subject">Live — %1$s gegen %2$s</string>
|
||||
<string name="wizard_share_chooser_live">Livestream teilen</string>
|
||||
<string name="wizard_action_share_regia_link">REGIE-LINK TEILEN</string>
|
||||
<string name="wizard_share_chooser_regia">Regie teilen</string>
|
||||
<string name="wizard_error_regia_link">Fehler beim Regie-Link</string>
|
||||
<string name="wizard_network_test_running_label">TEST LÄUFT...</string>
|
||||
<string name="wizard_network_test_start_label">NETZWERKTEST STARTEN</string>
|
||||
<string name="wizard_error_start_live">Fehler beim Starten des Livestreams</string>
|
||||
<string name="wizard_branding_opponent_name_placeholder">Name des Gegners</string>
|
||||
<string name="wizard_branding_team_fallback_name">Team</string>
|
||||
<string name="wizard_branding_edit_team_cd">Team bearbeiten</string>
|
||||
<string name="wizard_branding_customize_title">Anpassen</string>
|
||||
<string name="wizard_branding_team_name_label">Teamname</string>
|
||||
<string name="wizard_branding_logo_label">Logo</string>
|
||||
<string name="wizard_branding_upload_logo">LOGO HOCHLADEN</string>
|
||||
<string name="wizard_branding_remove_logo">ENTFERNEN</string>
|
||||
<string name="wizard_branding_color_label">Teamfarbe</string>
|
||||
<string name="wizard_branding_save">SPEICHERN</string>
|
||||
<string name="wizard_branding_cancel">ABBRECHEN</string>
|
||||
<string name="wizard_branding_no_logo">Kein Logo</string>
|
||||
|
||||
<string name="broadcast_snackbar_paused">Livestream pausiert</string>
|
||||
<string name="broadcast_snackbar_pause_error">Pause: %1$s</string>
|
||||
<string name="broadcast_snackbar_resumed">Livestream fortgesetzt</string>
|
||||
<string name="broadcast_snackbar_resume_error">Fortsetzen: %1$s</string>
|
||||
<string name="broadcast_snackbar_paused_remote">Von der Regie pausiert</string>
|
||||
<string name="broadcast_snackbar_resumed_remote">Von der Regie fortgesetzt</string>
|
||||
<string name="broadcast_snackbar_resume_rtmp_error">RTMP-Fortsetzung: %1$s</string>
|
||||
<string name="broadcast_snackbar_closed_remote">Livestream von der Regie beendet</string>
|
||||
<string name="broadcast_error_rtmp_missing">RTMP-URL fehlt</string>
|
||||
<string name="broadcast_error_session_unavailable">Sitzung nicht verfügbar</string>
|
||||
<string name="broadcast_status_paused">PAUSE</string>
|
||||
<string name="broadcast_status_live">LIVE</string>
|
||||
<string name="broadcast_status_connecting">VERBINDUNG…</string>
|
||||
<string name="broadcast_status_reconnecting">NEUVERBINDUNG…</string>
|
||||
<string name="broadcast_status_error_fallback">FEHLER</string>
|
||||
<string name="broadcast_permissions_required">Erlaube Kamera und Mikrofon, um live zu gehen</string>
|
||||
<string name="broadcast_permissions_grant_action">BERECHTIGUNGEN ERTEILEN</string>
|
||||
<string name="broadcast_share_link_unavailable">Live-Link noch nicht verfügbar</string>
|
||||
<string name="broadcast_share_subject_fallback">Match Live TV Livestream</string>
|
||||
<string name="broadcast_share_regia_subject">Regie-Link — %1$s</string>
|
||||
<string name="broadcast_error_regia_link">Fehler beim Regie-Link</string>
|
||||
<string name="broadcast_terminate_title">Livestream beenden?</string>
|
||||
<string name="broadcast_terminate_message">Der Stream wird für alle Zuschauer beendet.</string>
|
||||
<string name="broadcast_terminate_confirm">BEENDEN</string>
|
||||
<string name="broadcast_hide_controls_cd">Steuerung ausblenden</string>
|
||||
<string name="broadcast_show_controls_cd">Steuerung einblenden</string>
|
||||
<string name="broadcast_share_live_cd">Livestream teilen</string>
|
||||
<string name="broadcast_share_regia_cd">Regie-Link teilen</string>
|
||||
<string name="broadcast_next_period_cd">Nächste Periode</string>
|
||||
<string name="broadcast_resume_cd">Livestream fortsetzen</string>
|
||||
<string name="broadcast_pause_cd">Livestream pausieren</string>
|
||||
<string name="broadcast_terminate_cd">Livestream beenden</string>
|
||||
<string name="broadcast_team_home_label">HEIM</string>
|
||||
<string name="broadcast_team_away_label">GAST</string>
|
||||
<string name="broadcast_scoreboard_connected">Anzeigetafel OK</string>
|
||||
<string name="broadcast_scoreboard_offline">Anzeigetafel offline</string>
|
||||
<string name="broadcast_period_label_timed">Halbzeit %1$d</string>
|
||||
<string name="broadcast_set_progress">Satz %1$d · %2$d Pkt.</string>
|
||||
<string name="broadcast_team_sets_count">%1$d Sätze</string>
|
||||
<string name="broadcast_sets_won">Sätze gewonnen %1$d-%2$d</string>
|
||||
<string name="broadcast_side_home">Heim</string>
|
||||
<string name="broadcast_side_away">Gast</string>
|
||||
<string name="broadcast_tooltip_plus_side">+%1$d %2$s</string>
|
||||
<string name="broadcast_tooltip_add_point">Punkt hinzufügen %1$s</string>
|
||||
<string name="broadcast_tooltip_remove_point">Punkt entfernen %1$s</string>
|
||||
<string name="broadcast_share_chooser_title">Teilen</string>
|
||||
<string name="broadcast_close_set_button">SATZ BEENDEN</string>
|
||||
<string name="broadcast_points_target">%1$d Pkt.</string>
|
||||
|
||||
<string name="score_set_won_title">Satz beendet</string>
|
||||
<string name="score_set_won_message">%1$s gewinnt den Satz %2$d:%3$d.\n\nSatz beenden und zum nächsten wechseln?</string>
|
||||
<string name="score_action_close_set">Satz beenden</string>
|
||||
<string name="score_action_continue_scoring">Weiter punkten</string>
|
||||
<string name="score_close_set_anyway_message">Der Punktestand erfüllt die Turnierregeln noch nicht. Satz trotzdem beenden?</string>
|
||||
<string name="score_action_close_anyway">Trotzdem beenden</string>
|
||||
<string name="score_match_won_title">Spiel beendet</string>
|
||||
<string name="score_match_won_message">%1$s gewinnt das Spiel (%2$d:%3$d Sätze).\n\nLivestream endgültig beenden?</string>
|
||||
<string name="score_action_close_live">Livestream beenden</string>
|
||||
<string name="score_action_continue_live">Weiter senden</string>
|
||||
|
||||
<string name="sheet_choose_team">Team wählen</string>
|
||||
<string name="sheet_new_match_title">Neues Spiel</string>
|
||||
<string name="sheet_new_match_lead">Im Voraus planen oder die Live-Einrichtung sofort starten.</string>
|
||||
<string name="sheet_schedule_option">Spiel planen</string>
|
||||
<string name="sheet_schedule_option_sub">Datum, Uhrzeit und Gegner — auch auf der Website sichtbar</string>
|
||||
<string name="sheet_quick_option">Jetzt starten</string>
|
||||
<string name="sheet_quick_option_sub">Spiel erstellen und Wizard ohne Uhrzeit öffnen</string>
|
||||
<string name="sheet_schedule_title">Spiel planen</string>
|
||||
<string name="sheet_schedule_lead">Der Livestream startet jetzt nicht: Er erscheint auf der Website mit Datum und Uhrzeit. Du startest das Streaming in der App, wenn du in der Halle bist.</string>
|
||||
<string name="sheet_opponent">Gegner</string>
|
||||
<string name="sheet_location_optional">Ort (optional)</string>
|
||||
<string name="sheet_date_time">Datum und Uhrzeit</string>
|
||||
<string name="sheet_save_schedule">IM KALENDER SPEICHERN</string>
|
||||
<string name="sheet_choose_match">Spiel wählen</string>
|
||||
<string name="sheet_choose_match_lead">Bereits auf der Website oder in der App geplante Spiele.</string>
|
||||
<string name="sheet_section_scheduled">Geplant</string>
|
||||
<string name="sheet_section_unscheduled">Ohne Uhrzeit</string>
|
||||
<string name="sheet_badge_draft">ENTWURF</string>
|
||||
<string name="sheet_badge_scheduled">GEPLANT</string>
|
||||
<string name="sheet_badge_calendar">IM KALENDER</string>
|
||||
<string name="sheet_live_in_progress">Live läuft</string>
|
||||
<string name="sheet_status">Status: %1$s</string>
|
||||
<string name="sheet_resume_camera">KAMERA FORTSETZEN UND STREAMEN</string>
|
||||
<string name="sheet_continue_setup">EINRICHTUNG FORTSETZEN</string>
|
||||
<string name="sheet_configure_now_title">Jetzt einrichten?</string>
|
||||
<string name="sheet_configure_now_body">Du kannst die Übertragung jetzt vorbereiten oder zurückkommen, wenn du in der Halle bist.</string>
|
||||
<string name="sheet_configure">Einrichten</string>
|
||||
<string name="sheet_later">Später</string>
|
||||
<string name="sheet_delete_match_title">Spiel löschen</string>
|
||||
<string name="sheet_delete_match_body">«%1$s vs %2$s» löschen?
|
||||
|
||||
Dies kann nicht rückgängig gemacht werden.</string>
|
||||
<string name="sheet_delete">Löschen</string>
|
||||
<string name="sheet_resume_banner">Laufenden Livestream fortsetzen</string>
|
||||
<string name="match_status_resume">FORTSETZEN</string>
|
||||
<string name="match_status_live">LIVE</string>
|
||||
<string name="match_status_scheduled">GEPLANT</string>
|
||||
<string name="match_status_start">STARTEN</string>
|
||||
<string name="matches_msg_load_error">Ladefehler</string>
|
||||
<string name="matches_msg_resume_failed">Livestream konnte nicht fortgesetzt werden</string>
|
||||
<string name="matches_msg_create_failed">Spiel konnte nicht erstellt werden</string>
|
||||
<string name="matches_msg_scheduled_ok">Spiel geplant — auf der Website sichtbar</string>
|
||||
<string name="matches_msg_schedule_error">Fehler beim Erstellen des Spiels</string>
|
||||
<string name="matches_msg_deleted">Spiel gelöscht</string>
|
||||
<string name="matches_msg_delete_failed">Löschen fehlgeschlagen</string>
|
||||
<string name="login_email_placeholder">coach@team.com</string>
|
||||
<string name="action_delete">Löschen</string>
|
||||
<string name="wizard_color_hue">Farbton</string>
|
||||
</resources>
|
||||
|
||||
@@ -47,4 +47,198 @@
|
||||
<string name="streaming_notification_reconnecting">Reconnecting…</string>
|
||||
<string name="streaming_notification_error">Streaming error</string>
|
||||
<string name="streaming_notification_stop">Stop</string>
|
||||
|
||||
<string name="common_close">Close</string>
|
||||
<string name="common_error_generic">error</string>
|
||||
|
||||
<string name="wizard_step_title_match">01 · Match</string>
|
||||
<string name="wizard_step_title_transmission">02 · Broadcast</string>
|
||||
<string name="wizard_step_title_network">03 · Network test</string>
|
||||
<string name="wizard_match_not_found">Match not found</string>
|
||||
<string name="wizard_complete_transmission_step">Complete the Broadcast step</string>
|
||||
<string name="wizard_action_next">NEXT ></string>
|
||||
<string name="wizard_action_back">Back</string>
|
||||
<string name="wizard_action_start">START ></string>
|
||||
<string name="wizard_match_details_title">Match details</string>
|
||||
<string name="wizard_match_home_team_label">Home team</string>
|
||||
<string name="wizard_match_away_team_label">Away team</string>
|
||||
<string name="wizard_match_location_label">Location</string>
|
||||
<string name="wizard_match_category_label">Category (optional)</string>
|
||||
<string name="wizard_match_category_hint">E.g. Serie C, summer tournament — we\'ll use it in the description and overlay.</string>
|
||||
<string name="wizard_match_scheduled_label">Scheduled for</string>
|
||||
<string name="wizard_match_custom_overlay_label">Custom video overlay</string>
|
||||
<string name="wizard_match_custom_rules_label">Custom scoring rules</string>
|
||||
<string name="wizard_match_rules_standard_sport">Standard rules for the selected sport.</string>
|
||||
<string name="wizard_match_rules_custom_timed">Non-standard tournament: custom times and periods.</string>
|
||||
<string name="wizard_match_rules_custom_sets">Non-standard tournament: set your sets and points.</string>
|
||||
<string name="wizard_match_rules_standard_sets">FIVB standard: 3 sets to win, sets to 25, tie-break to 15.</string>
|
||||
<string name="wizard_match_periods_basket_label">Quarters</string>
|
||||
<string name="wizard_match_periods_timed_label">Halves</string>
|
||||
<string name="wizard_match_minutes_per_period_basket">Minutes per quarter</string>
|
||||
<string name="wizard_match_minutes_per_period_timed">Minutes per half</string>
|
||||
<string name="wizard_match_overtime_minutes_label">Overtime minutes</string>
|
||||
<string name="wizard_match_sets_to_win_label">Sets to win the match</string>
|
||||
<string name="wizard_match_points_per_set_label">Points to win a set</string>
|
||||
<string name="wizard_match_tiebreak_points_label">Tie-break points (last set)</string>
|
||||
<string name="wizard_error_opponent_name_required">Enter the opponent\'s name</string>
|
||||
<string name="wizard_error_points_per_set_required">Enter the points to win a set</string>
|
||||
<string name="wizard_error_tiebreak_points_required">Enter the tie-break points</string>
|
||||
<string name="wizard_error_period_duration_required">Enter the period duration in minutes</string>
|
||||
<string name="wizard_error_overtime_duration_required">Enter the overtime duration in minutes</string>
|
||||
<string name="wizard_error_save_generic">Error while saving</string>
|
||||
<string name="wizard_transmission_plan_label">Plan %1$s</string>
|
||||
<string name="wizard_transmission_platform_title">Platform</string>
|
||||
<string name="wizard_transmission_platform_site_subtitle">Live on our site (included)</string>
|
||||
<string name="wizard_transmission_youtube_activating">Channel being activated</string>
|
||||
<string name="wizard_transmission_youtube_premium_required">Premium Light or Full</string>
|
||||
<string name="wizard_transmission_youtube_badge">Premium</string>
|
||||
<string name="wizard_error_youtube_unavailable">YouTube not available for this team</string>
|
||||
<string name="wizard_transmission_visibility_title">Visibility</string>
|
||||
<string name="wizard_transmission_public_label">PUBLIC</string>
|
||||
<string name="wizard_transmission_unlisted_label">UNLISTED</string>
|
||||
<string name="wizard_transmission_public_desc">Shown in the live list on MatchLiveTV.it, in search and on the YouTube channel (if selected).</string>
|
||||
<string name="wizard_transmission_unlisted_desc">Not shown in public lists or search. Only those with the link can watch.</string>
|
||||
<string name="wizard_transmission_backend_note">The match always stays visible in the team backend for the whole subscription period.</string>
|
||||
<string name="wizard_error_session_create">Error creating session</string>
|
||||
<string name="wizard_network_test_title">Network test</string>
|
||||
<string name="wizard_network_test_subtitle">Check that your connection can handle the live upload.</string>
|
||||
<string name="wizard_network_download_label">Download</string>
|
||||
<string name="wizard_network_upload_label">Upload</string>
|
||||
<string name="wizard_network_latency_label">Latency</string>
|
||||
<string name="wizard_network_type_label">Network type</string>
|
||||
<string name="wizard_network_ready_label">READY TO GO LIVE</string>
|
||||
<string name="wizard_network_quality_label">Streaming quality (automatic)</string>
|
||||
<string name="wizard_network_link_youtube_label">YouTube link</string>
|
||||
<string name="wizard_network_link_live_label">Live link</string>
|
||||
<string name="wizard_action_copy">COPY</string>
|
||||
<string name="wizard_action_share">SHARE</string>
|
||||
<string name="wizard_network_share_subject">Live — %1$s vs %2$s</string>
|
||||
<string name="wizard_share_chooser_live">Share live stream</string>
|
||||
<string name="wizard_action_share_regia_link">SHARE CONTROL ROOM LINK</string>
|
||||
<string name="wizard_share_chooser_regia">Share control room</string>
|
||||
<string name="wizard_error_regia_link">Control room link error</string>
|
||||
<string name="wizard_network_test_running_label">TEST IN PROGRESS...</string>
|
||||
<string name="wizard_network_test_start_label">START NETWORK TEST</string>
|
||||
<string name="wizard_error_start_live">Error starting the live stream</string>
|
||||
<string name="wizard_branding_opponent_name_placeholder">Opponent name</string>
|
||||
<string name="wizard_branding_team_fallback_name">Team</string>
|
||||
<string name="wizard_branding_edit_team_cd">Edit team</string>
|
||||
<string name="wizard_branding_customize_title">Customize</string>
|
||||
<string name="wizard_branding_team_name_label">Team name</string>
|
||||
<string name="wizard_branding_logo_label">Logo</string>
|
||||
<string name="wizard_branding_upload_logo">UPLOAD LOGO</string>
|
||||
<string name="wizard_branding_remove_logo">REMOVE</string>
|
||||
<string name="wizard_branding_color_label">Team color</string>
|
||||
<string name="wizard_branding_save">SAVE</string>
|
||||
<string name="wizard_branding_cancel">CANCEL</string>
|
||||
<string name="wizard_branding_no_logo">No logo</string>
|
||||
|
||||
<string name="broadcast_snackbar_paused">Live paused</string>
|
||||
<string name="broadcast_snackbar_pause_error">Pause: %1$s</string>
|
||||
<string name="broadcast_snackbar_resumed">Live resumed</string>
|
||||
<string name="broadcast_snackbar_resume_error">Resume: %1$s</string>
|
||||
<string name="broadcast_snackbar_paused_remote">Paused from control room</string>
|
||||
<string name="broadcast_snackbar_resumed_remote">Resumed from control room</string>
|
||||
<string name="broadcast_snackbar_resume_rtmp_error">RTMP resume: %1$s</string>
|
||||
<string name="broadcast_snackbar_closed_remote">Live closed from control room</string>
|
||||
<string name="broadcast_error_rtmp_missing">Missing RTMP URL</string>
|
||||
<string name="broadcast_error_session_unavailable">Session not available</string>
|
||||
<string name="broadcast_status_paused">PAUSED</string>
|
||||
<string name="broadcast_status_live">LIVE</string>
|
||||
<string name="broadcast_status_connecting">CONNECTING…</string>
|
||||
<string name="broadcast_status_reconnecting">RECONNECTING…</string>
|
||||
<string name="broadcast_status_error_fallback">ERROR</string>
|
||||
<string name="broadcast_permissions_required">Allow camera and microphone to go live</string>
|
||||
<string name="broadcast_permissions_grant_action">GRANT PERMISSIONS</string>
|
||||
<string name="broadcast_share_link_unavailable">Live link not available yet</string>
|
||||
<string name="broadcast_share_subject_fallback">Match Live TV stream</string>
|
||||
<string name="broadcast_share_regia_subject">Control room link — %1$s</string>
|
||||
<string name="broadcast_error_regia_link">Control room link error</string>
|
||||
<string name="broadcast_terminate_title">End the live stream?</string>
|
||||
<string name="broadcast_terminate_message">The stream will be closed for all viewers.</string>
|
||||
<string name="broadcast_terminate_confirm">END</string>
|
||||
<string name="broadcast_hide_controls_cd">Hide controls</string>
|
||||
<string name="broadcast_show_controls_cd">Show controls</string>
|
||||
<string name="broadcast_share_live_cd">Share live stream</string>
|
||||
<string name="broadcast_share_regia_cd">Share control room link</string>
|
||||
<string name="broadcast_next_period_cd">Next period</string>
|
||||
<string name="broadcast_resume_cd">Resume live</string>
|
||||
<string name="broadcast_pause_cd">Pause live</string>
|
||||
<string name="broadcast_terminate_cd">End live</string>
|
||||
<string name="broadcast_team_home_label">HOME</string>
|
||||
<string name="broadcast_team_away_label">AWAY</string>
|
||||
<string name="broadcast_scoreboard_connected">Scoreboard OK</string>
|
||||
<string name="broadcast_scoreboard_offline">Scoreboard offline</string>
|
||||
<string name="broadcast_period_label_timed">Period %1$d</string>
|
||||
<string name="broadcast_set_progress">Set %1$d · %2$d pts</string>
|
||||
<string name="broadcast_team_sets_count">%1$d sets</string>
|
||||
<string name="broadcast_sets_won">Sets won %1$d-%2$d</string>
|
||||
<string name="broadcast_side_home">home</string>
|
||||
<string name="broadcast_side_away">away</string>
|
||||
<string name="broadcast_tooltip_plus_side">+%1$d %2$s</string>
|
||||
<string name="broadcast_tooltip_add_point">Add point %1$s</string>
|
||||
<string name="broadcast_tooltip_remove_point">Remove point %1$s</string>
|
||||
<string name="broadcast_share_chooser_title">Share</string>
|
||||
<string name="broadcast_close_set_button">CLOSE SET</string>
|
||||
<string name="broadcast_points_target">%1$d pts</string>
|
||||
|
||||
<string name="score_set_won_title">Set finished</string>
|
||||
<string name="score_set_won_message">%1$s wins the set %2$d-%3$d.\n\nClose the set and move to the next one?</string>
|
||||
<string name="score_action_close_set">Close set</string>
|
||||
<string name="score_action_continue_scoring">Keep scoring</string>
|
||||
<string name="score_close_set_anyway_message">The score doesn\'t meet the tournament rules yet. Close the set anyway?</string>
|
||||
<string name="score_action_close_anyway">Close anyway</string>
|
||||
<string name="score_match_won_title">Match finished</string>
|
||||
<string name="score_match_won_message">%1$s wins the match (%2$d-%3$d sets).\n\nEnd the live stream for good?</string>
|
||||
<string name="score_action_close_live">End live</string>
|
||||
<string name="score_action_continue_live">Keep streaming</string>
|
||||
|
||||
<string name="sheet_choose_team">Choose team</string>
|
||||
<string name="sheet_new_match_title">New match</string>
|
||||
<string name="sheet_new_match_lead">Schedule ahead or start live setup right away.</string>
|
||||
<string name="sheet_schedule_option">Schedule match</string>
|
||||
<string name="sheet_schedule_option_sub">Date, time and opponent — also visible on the site</string>
|
||||
<string name="sheet_quick_option">Start now</string>
|
||||
<string name="sheet_quick_option_sub">Create the match and open the wizard without a time</string>
|
||||
<string name="sheet_schedule_title">Schedule match</string>
|
||||
<string name="sheet_schedule_lead">Streaming does not start now: it will appear on the site with date and time. You will start streaming from the app when you are at the gym.</string>
|
||||
<string name="sheet_opponent">Opponent</string>
|
||||
<string name="sheet_location_optional">Location (optional)</string>
|
||||
<string name="sheet_date_time">Date and time</string>
|
||||
<string name="sheet_save_schedule">SAVE TO SCHEDULE</string>
|
||||
<string name="sheet_choose_match">Choose match</string>
|
||||
<string name="sheet_choose_match_lead">Matches already scheduled on the site or in the app.</string>
|
||||
<string name="sheet_section_scheduled">Scheduled</string>
|
||||
<string name="sheet_section_unscheduled">No time set</string>
|
||||
<string name="sheet_badge_draft">DRAFT</string>
|
||||
<string name="sheet_badge_scheduled">SCHEDULED</string>
|
||||
<string name="sheet_badge_calendar">ON CALENDAR</string>
|
||||
<string name="sheet_live_in_progress">Live in progress</string>
|
||||
<string name="sheet_status">Status: %1$s</string>
|
||||
<string name="sheet_resume_camera">RESUME CAMERA AND STREAM</string>
|
||||
<string name="sheet_continue_setup">CONTINUE SETUP</string>
|
||||
<string name="sheet_configure_now_title">Configure now?</string>
|
||||
<string name="sheet_configure_now_body">You can prepare the stream now, or come back when you are at the gym.</string>
|
||||
<string name="sheet_configure">Configure</string>
|
||||
<string name="sheet_later">Later</string>
|
||||
<string name="sheet_delete_match_title">Delete match</string>
|
||||
<string name="sheet_delete_match_body">Delete «%1$s vs %2$s»?
|
||||
|
||||
This cannot be undone.</string>
|
||||
<string name="sheet_delete">Delete</string>
|
||||
<string name="sheet_resume_banner">Resume live stream</string>
|
||||
<string name="match_status_resume">RESUME</string>
|
||||
<string name="match_status_live">LIVE</string>
|
||||
<string name="match_status_scheduled">SCHEDULED</string>
|
||||
<string name="match_status_start">START</string>
|
||||
<string name="matches_msg_load_error">Loading error</string>
|
||||
<string name="matches_msg_resume_failed">Could not resume the live stream</string>
|
||||
<string name="matches_msg_create_failed">Could not create the match</string>
|
||||
<string name="matches_msg_scheduled_ok">Match scheduled — visible on the site</string>
|
||||
<string name="matches_msg_schedule_error">Error creating match</string>
|
||||
<string name="matches_msg_deleted">Match deleted</string>
|
||||
<string name="matches_msg_delete_failed">Could not delete</string>
|
||||
<string name="login_email_placeholder">coach@team.com</string>
|
||||
<string name="action_delete">Delete</string>
|
||||
<string name="wizard_color_hue">Hue</string>
|
||||
</resources>
|
||||
|
||||
@@ -47,4 +47,198 @@
|
||||
<string name="streaming_notification_reconnecting">Reconectando…</string>
|
||||
<string name="streaming_notification_error">Error de streaming</string>
|
||||
<string name="streaming_notification_stop">Terminar</string>
|
||||
|
||||
<string name="common_close">Cerrar</string>
|
||||
<string name="common_error_generic">error</string>
|
||||
|
||||
<string name="wizard_step_title_match">01 · Partido</string>
|
||||
<string name="wizard_step_title_transmission">02 · Transmisión</string>
|
||||
<string name="wizard_step_title_network">03 · Test de red</string>
|
||||
<string name="wizard_match_not_found">Partido no encontrado</string>
|
||||
<string name="wizard_complete_transmission_step">Completa el paso Transmisión</string>
|
||||
<string name="wizard_action_next">SIGUIENTE ></string>
|
||||
<string name="wizard_action_back">Atrás</string>
|
||||
<string name="wizard_action_start">EMPEZAR ></string>
|
||||
<string name="wizard_match_details_title">Detalles del partido</string>
|
||||
<string name="wizard_match_home_team_label">Equipo local</string>
|
||||
<string name="wizard_match_away_team_label">Equipo visitante</string>
|
||||
<string name="wizard_match_location_label">Lugar</string>
|
||||
<string name="wizard_match_category_label">Categoría (opcional)</string>
|
||||
<string name="wizard_match_category_hint">Ej. Serie C, torneo de verano — lo usaremos en la descripción y el overlay.</string>
|
||||
<string name="wizard_match_scheduled_label">Programado para</string>
|
||||
<string name="wizard_match_custom_overlay_label">Overlay de vídeo personalizado</string>
|
||||
<string name="wizard_match_custom_rules_label">Reglas de puntuación personalizadas</string>
|
||||
<string name="wizard_match_rules_standard_sport">Reglas estándar del deporte seleccionado.</string>
|
||||
<string name="wizard_match_rules_custom_timed">Torneo no estándar: tiempos y periodos personalizados.</string>
|
||||
<string name="wizard_match_rules_custom_sets">Torneo no estándar: define sets y puntos.</string>
|
||||
<string name="wizard_match_rules_standard_sets">Estándar FIVB: 3 sets para ganar, sets a 25, tie-break a 15.</string>
|
||||
<string name="wizard_match_periods_basket_label">Cuartos</string>
|
||||
<string name="wizard_match_periods_timed_label">Tiempos</string>
|
||||
<string name="wizard_match_minutes_per_period_basket">Minutos por cuarto</string>
|
||||
<string name="wizard_match_minutes_per_period_timed">Minutos por tiempo</string>
|
||||
<string name="wizard_match_overtime_minutes_label">Minutos de prórroga</string>
|
||||
<string name="wizard_match_sets_to_win_label">Sets para ganar el partido</string>
|
||||
<string name="wizard_match_points_per_set_label">Puntos para ganar un set</string>
|
||||
<string name="wizard_match_tiebreak_points_label">Puntos del tie-break (último set)</string>
|
||||
<string name="wizard_error_opponent_name_required">Introduce el nombre del rival</string>
|
||||
<string name="wizard_error_points_per_set_required">Introduce los puntos para ganar un set</string>
|
||||
<string name="wizard_error_tiebreak_points_required">Introduce los puntos del tie-break</string>
|
||||
<string name="wizard_error_period_duration_required">Introduce la duración del periodo en minutos</string>
|
||||
<string name="wizard_error_overtime_duration_required">Introduce la duración de la prórroga en minutos</string>
|
||||
<string name="wizard_error_save_generic">Error al guardar</string>
|
||||
<string name="wizard_transmission_plan_label">Plan %1$s</string>
|
||||
<string name="wizard_transmission_platform_title">Plataforma</string>
|
||||
<string name="wizard_transmission_platform_site_subtitle">En directo en nuestro sitio (incluido)</string>
|
||||
<string name="wizard_transmission_youtube_activating">Canal en activación</string>
|
||||
<string name="wizard_transmission_youtube_premium_required">Premium Light o Full</string>
|
||||
<string name="wizard_transmission_youtube_badge">Premium</string>
|
||||
<string name="wizard_error_youtube_unavailable">YouTube no disponible para este equipo</string>
|
||||
<string name="wizard_transmission_visibility_title">Visibilidad</string>
|
||||
<string name="wizard_transmission_public_label">PÚBLICO</string>
|
||||
<string name="wizard_transmission_unlisted_label">NO LISTADO</string>
|
||||
<string name="wizard_transmission_public_desc">Aparece en la lista de directos de MatchLiveTV.it, en las búsquedas y en el canal de YouTube (si se selecciona).</string>
|
||||
<string name="wizard_transmission_unlisted_desc">No aparece en listas públicas ni en búsquedas. Solo puede verlo quien tenga el enlace.</string>
|
||||
<string name="wizard_transmission_backend_note">El partido permanece siempre visible en el backend del equipo durante toda la suscripción.</string>
|
||||
<string name="wizard_error_session_create">Error al crear la sesión</string>
|
||||
<string name="wizard_network_test_title">Test de red</string>
|
||||
<string name="wizard_network_test_subtitle">Comprueba que tu conexión soporta la subida del directo.</string>
|
||||
<string name="wizard_network_download_label">Descarga</string>
|
||||
<string name="wizard_network_upload_label">Subida</string>
|
||||
<string name="wizard_network_latency_label">Latencia</string>
|
||||
<string name="wizard_network_type_label">Tipo de red</string>
|
||||
<string name="wizard_network_ready_label">LISTO PARA EMITIR EN DIRECTO</string>
|
||||
<string name="wizard_network_quality_label">Calidad de streaming (automática)</string>
|
||||
<string name="wizard_network_link_youtube_label">Enlace de YouTube</string>
|
||||
<string name="wizard_network_link_live_label">Enlace del directo</string>
|
||||
<string name="wizard_action_copy">COPIAR</string>
|
||||
<string name="wizard_action_share">COMPARTIR</string>
|
||||
<string name="wizard_network_share_subject">Directo — %1$s vs %2$s</string>
|
||||
<string name="wizard_share_chooser_live">Compartir directo</string>
|
||||
<string name="wizard_action_share_regia_link">COMPARTIR ENLACE DE REGIE</string>
|
||||
<string name="wizard_share_chooser_regia">Compartir regie</string>
|
||||
<string name="wizard_error_regia_link">Error en el enlace de regie</string>
|
||||
<string name="wizard_network_test_running_label">TEST EN CURSO...</string>
|
||||
<string name="wizard_network_test_start_label">INICIAR TEST DE RED</string>
|
||||
<string name="wizard_error_start_live">Error al iniciar el directo</string>
|
||||
<string name="wizard_branding_opponent_name_placeholder">Nombre del rival</string>
|
||||
<string name="wizard_branding_team_fallback_name">Equipo</string>
|
||||
<string name="wizard_branding_edit_team_cd">Editar equipo</string>
|
||||
<string name="wizard_branding_customize_title">Personalizar</string>
|
||||
<string name="wizard_branding_team_name_label">Nombre del equipo</string>
|
||||
<string name="wizard_branding_logo_label">Logo</string>
|
||||
<string name="wizard_branding_upload_logo">SUBIR LOGO</string>
|
||||
<string name="wizard_branding_remove_logo">QUITAR</string>
|
||||
<string name="wizard_branding_color_label">Color del equipo</string>
|
||||
<string name="wizard_branding_save">GUARDAR</string>
|
||||
<string name="wizard_branding_cancel">CANCELAR</string>
|
||||
<string name="wizard_branding_no_logo">Sin logo</string>
|
||||
|
||||
<string name="broadcast_snackbar_paused">Directo en pausa</string>
|
||||
<string name="broadcast_snackbar_pause_error">Pausa: %1$s</string>
|
||||
<string name="broadcast_snackbar_resumed">Directo reanudado</string>
|
||||
<string name="broadcast_snackbar_resume_error">Reanudación: %1$s</string>
|
||||
<string name="broadcast_snackbar_paused_remote">Pausado desde regie</string>
|
||||
<string name="broadcast_snackbar_resumed_remote">Reanudado desde regie</string>
|
||||
<string name="broadcast_snackbar_resume_rtmp_error">Reanudación RTMP: %1$s</string>
|
||||
<string name="broadcast_snackbar_closed_remote">Directo cerrado desde regie</string>
|
||||
<string name="broadcast_error_rtmp_missing">Falta la URL RTMP</string>
|
||||
<string name="broadcast_error_session_unavailable">Sesión no disponible</string>
|
||||
<string name="broadcast_status_paused">PAUSA</string>
|
||||
<string name="broadcast_status_live">EN DIRECTO</string>
|
||||
<string name="broadcast_status_connecting">CONECTANDO…</string>
|
||||
<string name="broadcast_status_reconnecting">RECONECTANDO…</string>
|
||||
<string name="broadcast_status_error_fallback">ERROR</string>
|
||||
<string name="broadcast_permissions_required">Permite la cámara y el micrófono para salir en directo</string>
|
||||
<string name="broadcast_permissions_grant_action">CONCEDER PERMISOS</string>
|
||||
<string name="broadcast_share_link_unavailable">Enlace del directo aún no disponible</string>
|
||||
<string name="broadcast_share_subject_fallback">Directo de Match Live TV</string>
|
||||
<string name="broadcast_share_regia_subject">Enlace de regie — %1$s</string>
|
||||
<string name="broadcast_error_regia_link">Error en el enlace de regie</string>
|
||||
<string name="broadcast_terminate_title">¿Terminar el directo?</string>
|
||||
<string name="broadcast_terminate_message">El streaming se cerrará para todos los espectadores.</string>
|
||||
<string name="broadcast_terminate_confirm">TERMINAR</string>
|
||||
<string name="broadcast_hide_controls_cd">Ocultar controles</string>
|
||||
<string name="broadcast_show_controls_cd">Mostrar controles</string>
|
||||
<string name="broadcast_share_live_cd">Compartir directo</string>
|
||||
<string name="broadcast_share_regia_cd">Compartir enlace de regie</string>
|
||||
<string name="broadcast_next_period_cd">Periodo siguiente</string>
|
||||
<string name="broadcast_resume_cd">Reanudar directo</string>
|
||||
<string name="broadcast_pause_cd">Pausar directo</string>
|
||||
<string name="broadcast_terminate_cd">Terminar directo</string>
|
||||
<string name="broadcast_team_home_label">LOCAL</string>
|
||||
<string name="broadcast_team_away_label">VISITANTE</string>
|
||||
<string name="broadcast_scoreboard_connected">Marcador OK</string>
|
||||
<string name="broadcast_scoreboard_offline">Marcador sin conexión</string>
|
||||
<string name="broadcast_period_label_timed">Tiempo %1$d</string>
|
||||
<string name="broadcast_set_progress">Set %1$d · %2$d pts</string>
|
||||
<string name="broadcast_team_sets_count">%1$d sets</string>
|
||||
<string name="broadcast_sets_won">Sets ganados %1$d-%2$d</string>
|
||||
<string name="broadcast_side_home">local</string>
|
||||
<string name="broadcast_side_away">visitante</string>
|
||||
<string name="broadcast_tooltip_plus_side">+%1$d %2$s</string>
|
||||
<string name="broadcast_tooltip_add_point">Añadir punto %1$s</string>
|
||||
<string name="broadcast_tooltip_remove_point">Quitar punto %1$s</string>
|
||||
<string name="broadcast_share_chooser_title">Compartir</string>
|
||||
<string name="broadcast_close_set_button">CERRAR SET</string>
|
||||
<string name="broadcast_points_target">%1$d pts</string>
|
||||
|
||||
<string name="score_set_won_title">Set finalizado</string>
|
||||
<string name="score_set_won_message">%1$s gana el set %2$d-%3$d.\n\n¿Cerrar el set y pasar al siguiente?</string>
|
||||
<string name="score_action_close_set">Cerrar set</string>
|
||||
<string name="score_action_continue_scoring">Seguir puntuando</string>
|
||||
<string name="score_close_set_anyway_message">El marcador aún no cumple las reglas del torneo. ¿Cerrar el set de todas formas?</string>
|
||||
<string name="score_action_close_anyway">Cerrar de todas formas</string>
|
||||
<string name="score_match_won_title">Partido finalizado</string>
|
||||
<string name="score_match_won_message">%1$s gana el partido (%2$d-%3$d sets).\n\n¿Cerrar definitivamente el directo?</string>
|
||||
<string name="score_action_close_live">Cerrar directo</string>
|
||||
<string name="score_action_continue_live">Seguir en directo</string>
|
||||
|
||||
<string name="sheet_choose_team">Elegir equipo</string>
|
||||
<string name="sheet_new_match_title">Nuevo partido</string>
|
||||
<string name="sheet_new_match_lead">Programa con antelación o inicia ya la configuración del directo.</string>
|
||||
<string name="sheet_schedule_option">Programar partido</string>
|
||||
<string name="sheet_schedule_option_sub">Fecha, hora y rival — también visible en el sitio</string>
|
||||
<string name="sheet_quick_option">Empezar ahora</string>
|
||||
<string name="sheet_quick_option_sub">Crea el partido y abre el asistente sin horario</string>
|
||||
<string name="sheet_schedule_title">Programar partido</string>
|
||||
<string name="sheet_schedule_lead">El directo no empieza ahora: aparecerá en el sitio con fecha y hora. Iniciarás el streaming desde la app cuando estés en el pabellón.</string>
|
||||
<string name="sheet_opponent">Rival</string>
|
||||
<string name="sheet_location_optional">Lugar (opcional)</string>
|
||||
<string name="sheet_date_time">Fecha y hora</string>
|
||||
<string name="sheet_save_schedule">GUARDAR EN EL CALENDARIO</string>
|
||||
<string name="sheet_choose_match">Elegir partido</string>
|
||||
<string name="sheet_choose_match_lead">Partidos ya programados en el sitio o en la app.</string>
|
||||
<string name="sheet_section_scheduled">Programados</string>
|
||||
<string name="sheet_section_unscheduled">Sin horario</string>
|
||||
<string name="sheet_badge_draft">BORRADOR</string>
|
||||
<string name="sheet_badge_scheduled">PROGRAMADO</string>
|
||||
<string name="sheet_badge_calendar">EN CALENDARIO</string>
|
||||
<string name="sheet_live_in_progress">Directo en curso</string>
|
||||
<string name="sheet_status">Estado: %1$s</string>
|
||||
<string name="sheet_resume_camera">REANUDAR CÁMARA Y EMITIR</string>
|
||||
<string name="sheet_continue_setup">CONTINUAR CONFIGURACIÓN</string>
|
||||
<string name="sheet_configure_now_title">¿Configurar ahora?</string>
|
||||
<string name="sheet_configure_now_body">Puedes preparar la emisión ahora o volver cuando estés en el pabellón.</string>
|
||||
<string name="sheet_configure">Configurar</string>
|
||||
<string name="sheet_later">Más tarde</string>
|
||||
<string name="sheet_delete_match_title">Eliminar partido</string>
|
||||
<string name="sheet_delete_match_body">¿Eliminar «%1$s vs %2$s»?
|
||||
|
||||
Esta acción no se puede deshacer.</string>
|
||||
<string name="sheet_delete">Eliminar</string>
|
||||
<string name="sheet_resume_banner">Reanudar directo en curso</string>
|
||||
<string name="match_status_resume">REANUDAR</string>
|
||||
<string name="match_status_live">EN DIRECTO</string>
|
||||
<string name="match_status_scheduled">PROGRAMADO</string>
|
||||
<string name="match_status_start">INICIAR</string>
|
||||
<string name="matches_msg_load_error">Error de carga</string>
|
||||
<string name="matches_msg_resume_failed">No se pudo reanudar el directo</string>
|
||||
<string name="matches_msg_create_failed">No se pudo crear el partido</string>
|
||||
<string name="matches_msg_scheduled_ok">Partido programado — visible en el sitio</string>
|
||||
<string name="matches_msg_schedule_error">Error al crear el partido</string>
|
||||
<string name="matches_msg_deleted">Partido eliminado</string>
|
||||
<string name="matches_msg_delete_failed">No se pudo eliminar</string>
|
||||
<string name="login_email_placeholder">coach@equipo.com</string>
|
||||
<string name="action_delete">Eliminar</string>
|
||||
<string name="wizard_color_hue">Tono</string>
|
||||
</resources>
|
||||
|
||||
@@ -47,4 +47,198 @@
|
||||
<string name="streaming_notification_reconnecting">Reconnexion…</string>
|
||||
<string name="streaming_notification_error">Erreur de streaming</string>
|
||||
<string name="streaming_notification_stop">Arrêter</string>
|
||||
|
||||
<string name="common_close">Fermer</string>
|
||||
<string name="common_error_generic">erreur</string>
|
||||
|
||||
<string name="wizard_step_title_match">01 · Match</string>
|
||||
<string name="wizard_step_title_transmission">02 · Diffusion</string>
|
||||
<string name="wizard_step_title_network">03 · Test réseau</string>
|
||||
<string name="wizard_match_not_found">Match introuvable</string>
|
||||
<string name="wizard_complete_transmission_step">Complétez l\'étape Diffusion</string>
|
||||
<string name="wizard_action_next">SUIVANT ></string>
|
||||
<string name="wizard_action_back">Retour</string>
|
||||
<string name="wizard_action_start">DÉMARRER ></string>
|
||||
<string name="wizard_match_details_title">Détails du match</string>
|
||||
<string name="wizard_match_home_team_label">Équipe à domicile</string>
|
||||
<string name="wizard_match_away_team_label">Équipe adverse</string>
|
||||
<string name="wizard_match_location_label">Lieu</string>
|
||||
<string name="wizard_match_category_label">Championnat (facultatif)</string>
|
||||
<string name="wizard_match_category_hint">Ex. Serie C, tournoi d\'été — utilisé dans la description et l\'overlay.</string>
|
||||
<string name="wizard_match_scheduled_label">Programmé pour</string>
|
||||
<string name="wizard_match_custom_overlay_label">Overlay vidéo personnalisé</string>
|
||||
<string name="wizard_match_custom_rules_label">Règles de score personnalisées</string>
|
||||
<string name="wizard_match_rules_standard_sport">Règles standard du sport sélectionné.</string>
|
||||
<string name="wizard_match_rules_custom_timed">Tournoi non standard : temps et périodes personnalisés.</string>
|
||||
<string name="wizard_match_rules_custom_sets">Tournoi non standard : définissez sets et points.</string>
|
||||
<string name="wizard_match_rules_standard_sets">Standard FIVB : 3 sets gagnants, sets à 25, tie-break à 15.</string>
|
||||
<string name="wizard_match_periods_basket_label">Quart-temps</string>
|
||||
<string name="wizard_match_periods_timed_label">Mi-temps</string>
|
||||
<string name="wizard_match_minutes_per_period_basket">Minutes par quart-temps</string>
|
||||
<string name="wizard_match_minutes_per_period_timed">Minutes par mi-temps</string>
|
||||
<string name="wizard_match_overtime_minutes_label">Minutes de prolongation</string>
|
||||
<string name="wizard_match_sets_to_win_label">Sets pour gagner le match</string>
|
||||
<string name="wizard_match_points_per_set_label">Points pour gagner un set</string>
|
||||
<string name="wizard_match_tiebreak_points_label">Points du tie-break (dernier set)</string>
|
||||
<string name="wizard_error_opponent_name_required">Saisissez le nom de l\'adversaire</string>
|
||||
<string name="wizard_error_points_per_set_required">Saisissez les points pour gagner un set</string>
|
||||
<string name="wizard_error_tiebreak_points_required">Saisissez les points du tie-break</string>
|
||||
<string name="wizard_error_period_duration_required">Saisissez la durée de la période en minutes</string>
|
||||
<string name="wizard_error_overtime_duration_required">Saisissez la durée de la prolongation en minutes</string>
|
||||
<string name="wizard_error_save_generic">Erreur lors de l\'enregistrement</string>
|
||||
<string name="wizard_transmission_plan_label">Forfait %1$s</string>
|
||||
<string name="wizard_transmission_platform_title">Plateforme</string>
|
||||
<string name="wizard_transmission_platform_site_subtitle">Direct sur notre site (inclus)</string>
|
||||
<string name="wizard_transmission_youtube_activating">Chaîne en cours d\'activation</string>
|
||||
<string name="wizard_transmission_youtube_premium_required">Premium Light ou Full</string>
|
||||
<string name="wizard_transmission_youtube_badge">Premium</string>
|
||||
<string name="wizard_error_youtube_unavailable">YouTube non disponible pour cette équipe</string>
|
||||
<string name="wizard_transmission_visibility_title">Visibilité</string>
|
||||
<string name="wizard_transmission_public_label">PUBLIC</string>
|
||||
<string name="wizard_transmission_unlisted_label">NON RÉPERTORIÉ</string>
|
||||
<string name="wizard_transmission_public_desc">Apparaît dans la liste des directs sur MatchLiveTV.it, dans les recherches et sur la chaîne YouTube (si sélectionnée).</string>
|
||||
<string name="wizard_transmission_unlisted_desc">N\'apparaît pas dans les listes publiques ni dans les recherches. Seules les personnes ayant le lien peuvent regarder.</string>
|
||||
<string name="wizard_transmission_backend_note">Le match reste toujours visible dans le backend de l\'équipe pendant toute la durée de l\'abonnement.</string>
|
||||
<string name="wizard_error_session_create">Erreur lors de la création de la session</string>
|
||||
<string name="wizard_network_test_title">Test réseau</string>
|
||||
<string name="wizard_network_test_subtitle">Vérifiez que votre connexion supporte l\'envoi du direct.</string>
|
||||
<string name="wizard_network_download_label">Téléchargement</string>
|
||||
<string name="wizard_network_upload_label">Envoi</string>
|
||||
<string name="wizard_network_latency_label">Latence</string>
|
||||
<string name="wizard_network_type_label">Type de réseau</string>
|
||||
<string name="wizard_network_ready_label">PRÊT À PASSER EN DIRECT</string>
|
||||
<string name="wizard_network_quality_label">Qualité de streaming (automatique)</string>
|
||||
<string name="wizard_network_link_youtube_label">Lien YouTube</string>
|
||||
<string name="wizard_network_link_live_label">Lien du direct</string>
|
||||
<string name="wizard_action_copy">COPIER</string>
|
||||
<string name="wizard_action_share">PARTAGER</string>
|
||||
<string name="wizard_network_share_subject">Direct — %1$s vs %2$s</string>
|
||||
<string name="wizard_share_chooser_live">Partager le direct</string>
|
||||
<string name="wizard_action_share_regia_link">PARTAGER LE LIEN RÉGIE</string>
|
||||
<string name="wizard_share_chooser_regia">Partager la régie</string>
|
||||
<string name="wizard_error_regia_link">Erreur du lien régie</string>
|
||||
<string name="wizard_network_test_running_label">TEST EN COURS...</string>
|
||||
<string name="wizard_network_test_start_label">LANCER LE TEST RÉSEAU</string>
|
||||
<string name="wizard_error_start_live">Erreur au démarrage du direct</string>
|
||||
<string name="wizard_branding_opponent_name_placeholder">Nom de l\'adversaire</string>
|
||||
<string name="wizard_branding_team_fallback_name">Équipe</string>
|
||||
<string name="wizard_branding_edit_team_cd">Modifier l\'équipe</string>
|
||||
<string name="wizard_branding_customize_title">Personnaliser</string>
|
||||
<string name="wizard_branding_team_name_label">Nom de l\'équipe</string>
|
||||
<string name="wizard_branding_logo_label">Logo</string>
|
||||
<string name="wizard_branding_upload_logo">CHARGER LE LOGO</string>
|
||||
<string name="wizard_branding_remove_logo">SUPPRIMER</string>
|
||||
<string name="wizard_branding_color_label">Couleur de l\'équipe</string>
|
||||
<string name="wizard_branding_save">ENREGISTRER</string>
|
||||
<string name="wizard_branding_cancel">ANNULER</string>
|
||||
<string name="wizard_branding_no_logo">Aucun logo</string>
|
||||
|
||||
<string name="broadcast_snackbar_paused">Direct en pause</string>
|
||||
<string name="broadcast_snackbar_pause_error">Pause : %1$s</string>
|
||||
<string name="broadcast_snackbar_resumed">Direct repris</string>
|
||||
<string name="broadcast_snackbar_resume_error">Reprise : %1$s</string>
|
||||
<string name="broadcast_snackbar_paused_remote">Mis en pause depuis la régie</string>
|
||||
<string name="broadcast_snackbar_resumed_remote">Repris depuis la régie</string>
|
||||
<string name="broadcast_snackbar_resume_rtmp_error">Reprise RTMP : %1$s</string>
|
||||
<string name="broadcast_snackbar_closed_remote">Direct fermé depuis la régie</string>
|
||||
<string name="broadcast_error_rtmp_missing">URL RTMP manquante</string>
|
||||
<string name="broadcast_error_session_unavailable">Session non disponible</string>
|
||||
<string name="broadcast_status_paused">PAUSE</string>
|
||||
<string name="broadcast_status_live">EN DIRECT</string>
|
||||
<string name="broadcast_status_connecting">CONNEXION…</string>
|
||||
<string name="broadcast_status_reconnecting">RECONNEXION…</string>
|
||||
<string name="broadcast_status_error_fallback">ERREUR</string>
|
||||
<string name="broadcast_permissions_required">Autorisez la caméra et le micro pour passer en direct</string>
|
||||
<string name="broadcast_permissions_grant_action">ACCORDER LES AUTORISATIONS</string>
|
||||
<string name="broadcast_share_link_unavailable">Lien du direct pas encore disponible</string>
|
||||
<string name="broadcast_share_subject_fallback">Direct Match Live TV</string>
|
||||
<string name="broadcast_share_regia_subject">Lien régie — %1$s</string>
|
||||
<string name="broadcast_error_regia_link">Erreur du lien régie</string>
|
||||
<string name="broadcast_terminate_title">Terminer le direct ?</string>
|
||||
<string name="broadcast_terminate_message">Le streaming sera fermé pour tous les spectateurs.</string>
|
||||
<string name="broadcast_terminate_confirm">TERMINER</string>
|
||||
<string name="broadcast_hide_controls_cd">Masquer les commandes</string>
|
||||
<string name="broadcast_show_controls_cd">Afficher les commandes</string>
|
||||
<string name="broadcast_share_live_cd">Partager le direct</string>
|
||||
<string name="broadcast_share_regia_cd">Partager le lien régie</string>
|
||||
<string name="broadcast_next_period_cd">Période suivante</string>
|
||||
<string name="broadcast_resume_cd">Reprendre le direct</string>
|
||||
<string name="broadcast_pause_cd">Mettre le direct en pause</string>
|
||||
<string name="broadcast_terminate_cd">Terminer le direct</string>
|
||||
<string name="broadcast_team_home_label">DOMICILE</string>
|
||||
<string name="broadcast_team_away_label">EXTÉRIEUR</string>
|
||||
<string name="broadcast_scoreboard_connected">Tableau OK</string>
|
||||
<string name="broadcast_scoreboard_offline">Tableau hors ligne</string>
|
||||
<string name="broadcast_period_label_timed">Période %1$d</string>
|
||||
<string name="broadcast_set_progress">Set %1$d · %2$d pts</string>
|
||||
<string name="broadcast_team_sets_count">%1$d sets</string>
|
||||
<string name="broadcast_sets_won">Sets gagnés %1$d-%2$d</string>
|
||||
<string name="broadcast_side_home">domicile</string>
|
||||
<string name="broadcast_side_away">extérieur</string>
|
||||
<string name="broadcast_tooltip_plus_side">+%1$d %2$s</string>
|
||||
<string name="broadcast_tooltip_add_point">Ajouter un point %1$s</string>
|
||||
<string name="broadcast_tooltip_remove_point">Retirer un point %1$s</string>
|
||||
<string name="broadcast_share_chooser_title">Partager</string>
|
||||
<string name="broadcast_close_set_button">FERMER LE SET</string>
|
||||
<string name="broadcast_points_target">%1$d pts</string>
|
||||
|
||||
<string name="score_set_won_title">Set terminé</string>
|
||||
<string name="score_set_won_message">%1$s remporte le set %2$d-%3$d.\n\nFermer le set et passer au suivant ?</string>
|
||||
<string name="score_action_close_set">Fermer le set</string>
|
||||
<string name="score_action_continue_scoring">Continuer à marquer</string>
|
||||
<string name="score_close_set_anyway_message">Le score ne respecte pas encore les règles du tournoi. Fermer le set quand même ?</string>
|
||||
<string name="score_action_close_anyway">Fermer quand même</string>
|
||||
<string name="score_match_won_title">Match terminé</string>
|
||||
<string name="score_match_won_message">%1$s remporte le match (%2$d-%3$d sets).\n\nFermer définitivement le direct ?</string>
|
||||
<string name="score_action_close_live">Fermer le direct</string>
|
||||
<string name="score_action_continue_live">Continuer le direct</string>
|
||||
|
||||
<string name="sheet_choose_team">Choisir l\'équipe</string>
|
||||
<string name="sheet_new_match_title">Nouveau match</string>
|
||||
<string name="sheet_new_match_lead">Planifiez à l\'avance ou lancez la configuration du direct tout de suite.</string>
|
||||
<string name="sheet_schedule_option">Planifier le match</string>
|
||||
<string name="sheet_schedule_option_sub">Date, heure et adversaire — aussi visibles sur le site</string>
|
||||
<string name="sheet_quick_option">Démarrer maintenant</string>
|
||||
<string name="sheet_quick_option_sub">Créez le match et ouvrez l\'assistant sans horaire</string>
|
||||
<string name="sheet_schedule_title">Planifier le match</string>
|
||||
<string name="sheet_schedule_lead">Le direct ne démarre pas maintenant : il apparaîtra sur le site avec date et heure. Vous lancerez le streaming depuis l\'app une fois en salle.</string>
|
||||
<string name="sheet_opponent">Adversaire</string>
|
||||
<string name="sheet_location_optional">Lieu (facultatif)</string>
|
||||
<string name="sheet_date_time">Date et heure</string>
|
||||
<string name="sheet_save_schedule">ENREGISTRER AU CALENDRIER</string>
|
||||
<string name="sheet_choose_match">Choisir le match</string>
|
||||
<string name="sheet_choose_match_lead">Matchs déjà planifiés sur le site ou dans l\'app.</string>
|
||||
<string name="sheet_section_scheduled">Planifiés</string>
|
||||
<string name="sheet_section_unscheduled">Sans horaire</string>
|
||||
<string name="sheet_badge_draft">BROUILLON</string>
|
||||
<string name="sheet_badge_scheduled">PLANIFIÉ</string>
|
||||
<string name="sheet_badge_calendar">AU CALENDRIER</string>
|
||||
<string name="sheet_live_in_progress">Direct en cours</string>
|
||||
<string name="sheet_status">État : %1$s</string>
|
||||
<string name="sheet_resume_camera">REPRENDRE CAMÉRA ET DIFFUSER</string>
|
||||
<string name="sheet_continue_setup">CONTINUER LA CONFIGURATION</string>
|
||||
<string name="sheet_configure_now_title">Configurer maintenant ?</string>
|
||||
<string name="sheet_configure_now_body">Vous pouvez préparer la diffusion maintenant, ou revenir une fois en salle.</string>
|
||||
<string name="sheet_configure">Configurer</string>
|
||||
<string name="sheet_later">Plus tard</string>
|
||||
<string name="sheet_delete_match_title">Supprimer le match</string>
|
||||
<string name="sheet_delete_match_body">Supprimer « %1$s vs %2$s » ?
|
||||
|
||||
Cette action est irréversible.</string>
|
||||
<string name="sheet_delete">Supprimer</string>
|
||||
<string name="sheet_resume_banner">Reprendre le direct en cours</string>
|
||||
<string name="match_status_resume">REPRENDRE</string>
|
||||
<string name="match_status_live">EN DIRECT</string>
|
||||
<string name="match_status_scheduled">PLANIFIÉ</string>
|
||||
<string name="match_status_start">DÉMARRER</string>
|
||||
<string name="matches_msg_load_error">Erreur de chargement</string>
|
||||
<string name="matches_msg_resume_failed">Impossible de reprendre le direct</string>
|
||||
<string name="matches_msg_create_failed">Impossible de créer le match</string>
|
||||
<string name="matches_msg_scheduled_ok">Match planifié — visible sur le site</string>
|
||||
<string name="matches_msg_schedule_error">Erreur lors de la création du match</string>
|
||||
<string name="matches_msg_deleted">Match supprimé</string>
|
||||
<string name="matches_msg_delete_failed">Impossible de supprimer</string>
|
||||
<string name="login_email_placeholder">coach@equipe.com</string>
|
||||
<string name="action_delete">Supprimer</string>
|
||||
<string name="wizard_color_hue">Teinte</string>
|
||||
</resources>
|
||||
|
||||
@@ -47,4 +47,198 @@
|
||||
<string name="streaming_notification_reconnecting">Riconnessione…</string>
|
||||
<string name="streaming_notification_error">Errore streaming</string>
|
||||
<string name="streaming_notification_stop">Termina</string>
|
||||
|
||||
<string name="common_close">Chiudi</string>
|
||||
<string name="common_error_generic">errore</string>
|
||||
|
||||
<string name="wizard_step_title_match">01 · Partita</string>
|
||||
<string name="wizard_step_title_transmission">02 · Trasmissione</string>
|
||||
<string name="wizard_step_title_network">03 · Test rete</string>
|
||||
<string name="wizard_match_not_found">Partita non trovata</string>
|
||||
<string name="wizard_complete_transmission_step">Completa lo step Trasmissione</string>
|
||||
<string name="wizard_action_next">AVANTI ></string>
|
||||
<string name="wizard_action_back">Indietro</string>
|
||||
<string name="wizard_action_start">INIZIA ></string>
|
||||
<string name="wizard_match_details_title">Dettagli partita</string>
|
||||
<string name="wizard_match_home_team_label">Squadra di casa</string>
|
||||
<string name="wizard_match_away_team_label">Squadra avversaria</string>
|
||||
<string name="wizard_match_location_label">Luogo</string>
|
||||
<string name="wizard_match_category_label">Campionato (facoltativo)</string>
|
||||
<string name="wizard_match_category_hint">Es. Serie C, torneo estivo — lo useremo in descrizione e overlay.</string>
|
||||
<string name="wizard_match_scheduled_label">Programmata per</string>
|
||||
<string name="wizard_match_custom_overlay_label">Overlay video personalizzato</string>
|
||||
<string name="wizard_match_custom_rules_label">Regole punteggio personalizzate</string>
|
||||
<string name="wizard_match_rules_standard_sport">Regole standard dello sport selezionato.</string>
|
||||
<string name="wizard_match_rules_custom_timed">Torneo non standard: tempi e periodi personalizzati.</string>
|
||||
<string name="wizard_match_rules_custom_sets">Torneo non standard: imposta set e punteggi.</string>
|
||||
<string name="wizard_match_rules_standard_sets">Standard FIPAV: 3 set per vincere, set a 25, tie-break a 15.</string>
|
||||
<string name="wizard_match_periods_basket_label">Quarti</string>
|
||||
<string name="wizard_match_periods_timed_label">Tempi</string>
|
||||
<string name="wizard_match_minutes_per_period_basket">Minuti per quarto</string>
|
||||
<string name="wizard_match_minutes_per_period_timed">Minuti per tempo</string>
|
||||
<string name="wizard_match_overtime_minutes_label">Minuti supplementari</string>
|
||||
<string name="wizard_match_sets_to_win_label">Set da vincere la partita</string>
|
||||
<string name="wizard_match_points_per_set_label">Punti per vincere un set</string>
|
||||
<string name="wizard_match_tiebreak_points_label">Punti tie-break (ultimo set)</string>
|
||||
<string name="wizard_error_opponent_name_required">Inserisci il nome avversario</string>
|
||||
<string name="wizard_error_points_per_set_required">Inserisci i punti per vincere un set</string>
|
||||
<string name="wizard_error_tiebreak_points_required">Inserisci i punti del tie-break</string>
|
||||
<string name="wizard_error_period_duration_required">Inserisci la durata del periodo in minuti</string>
|
||||
<string name="wizard_error_overtime_duration_required">Inserisci la durata dei supplementari in minuti</string>
|
||||
<string name="wizard_error_save_generic">Errore nel salvataggio</string>
|
||||
<string name="wizard_transmission_plan_label">Piano %1$s</string>
|
||||
<string name="wizard_transmission_platform_title">Piattaforma</string>
|
||||
<string name="wizard_transmission_platform_site_subtitle">Diretta sul nostro sito (incluso)</string>
|
||||
<string name="wizard_transmission_youtube_activating">Canale in attivazione</string>
|
||||
<string name="wizard_transmission_youtube_premium_required">Premium Light o Full</string>
|
||||
<string name="wizard_transmission_youtube_badge">Premium</string>
|
||||
<string name="wizard_error_youtube_unavailable">YouTube non disponibile per questa squadra</string>
|
||||
<string name="wizard_transmission_visibility_title">Visibilità</string>
|
||||
<string name="wizard_transmission_public_label">PUBBLICO</string>
|
||||
<string name="wizard_transmission_unlisted_label">NON IN ELENCO</string>
|
||||
<string name="wizard_transmission_public_desc">Compare nell\'elenco dirette su MatchLiveTV.it, nelle ricerche e sul canale YouTube (se selezionato).</string>
|
||||
<string name="wizard_transmission_unlisted_desc">Non compare negli elenchi pubblici né nelle ricerche. Solo chi ha il link può guardare.</string>
|
||||
<string name="wizard_transmission_backend_note">La partita resta sempre visibile nel backend della squadra per tutta la durata dell\'abbonamento.</string>
|
||||
<string name="wizard_error_session_create">Errore creazione sessione</string>
|
||||
<string name="wizard_network_test_title">Test rete</string>
|
||||
<string name="wizard_network_test_subtitle">Verifica che la connessione regga l\'upload della diretta.</string>
|
||||
<string name="wizard_network_download_label">Download</string>
|
||||
<string name="wizard_network_upload_label">Upload</string>
|
||||
<string name="wizard_network_latency_label">Latenza</string>
|
||||
<string name="wizard_network_type_label">Tipo rete</string>
|
||||
<string name="wizard_network_ready_label">PRONTO PER ANDARE IN DIRETTA</string>
|
||||
<string name="wizard_network_quality_label">Qualità streaming (automatica)</string>
|
||||
<string name="wizard_network_link_youtube_label">Link YouTube</string>
|
||||
<string name="wizard_network_link_live_label">Link diretta</string>
|
||||
<string name="wizard_action_copy">COPIA</string>
|
||||
<string name="wizard_action_share">CONDIVIDI</string>
|
||||
<string name="wizard_network_share_subject">Diretta — %1$s vs %2$s</string>
|
||||
<string name="wizard_share_chooser_live">Condividi diretta</string>
|
||||
<string name="wizard_action_share_regia_link">CONDIVIDI LINK REGIA</string>
|
||||
<string name="wizard_share_chooser_regia">Condividi regia</string>
|
||||
<string name="wizard_error_regia_link">Errore link regia</string>
|
||||
<string name="wizard_network_test_running_label">TEST IN CORSO...</string>
|
||||
<string name="wizard_network_test_start_label">AVVIA TEST RETE</string>
|
||||
<string name="wizard_error_start_live">Errore avvio diretta</string>
|
||||
<string name="wizard_branding_opponent_name_placeholder">Nome avversario</string>
|
||||
<string name="wizard_branding_team_fallback_name">Squadra</string>
|
||||
<string name="wizard_branding_edit_team_cd">Modifica squadra</string>
|
||||
<string name="wizard_branding_customize_title">Personalizza</string>
|
||||
<string name="wizard_branding_team_name_label">Nome squadra</string>
|
||||
<string name="wizard_branding_logo_label">Logo</string>
|
||||
<string name="wizard_branding_upload_logo">CARICA LOGO</string>
|
||||
<string name="wizard_branding_remove_logo">RIMUOVI</string>
|
||||
<string name="wizard_branding_color_label">Colore squadra</string>
|
||||
<string name="wizard_branding_save">SALVA</string>
|
||||
<string name="wizard_branding_cancel">ANNULLA</string>
|
||||
<string name="wizard_branding_no_logo">Nessun logo</string>
|
||||
|
||||
<string name="broadcast_snackbar_paused">Diretta in pausa</string>
|
||||
<string name="broadcast_snackbar_pause_error">Pausa: %1$s</string>
|
||||
<string name="broadcast_snackbar_resumed">Diretta ripresa</string>
|
||||
<string name="broadcast_snackbar_resume_error">Ripresa: %1$s</string>
|
||||
<string name="broadcast_snackbar_paused_remote">Pausa dalla regia</string>
|
||||
<string name="broadcast_snackbar_resumed_remote">Ripresa dalla regia</string>
|
||||
<string name="broadcast_snackbar_resume_rtmp_error">Ripresa RTMP: %1$s</string>
|
||||
<string name="broadcast_snackbar_closed_remote">Diretta chiusa dalla regia</string>
|
||||
<string name="broadcast_error_rtmp_missing">URL RTMP mancante</string>
|
||||
<string name="broadcast_error_session_unavailable">Sessione non disponibile</string>
|
||||
<string name="broadcast_status_paused">PAUSA</string>
|
||||
<string name="broadcast_status_live">IN DIRETTA</string>
|
||||
<string name="broadcast_status_connecting">CONNESSIONE…</string>
|
||||
<string name="broadcast_status_reconnecting">RICONNESSIONE…</string>
|
||||
<string name="broadcast_status_error_fallback">ERRORE</string>
|
||||
<string name="broadcast_permissions_required">Consenti camera e microfono per andare in diretta</string>
|
||||
<string name="broadcast_permissions_grant_action">CONCEDI PERMESSI</string>
|
||||
<string name="broadcast_share_link_unavailable">Link diretta non ancora disponibile</string>
|
||||
<string name="broadcast_share_subject_fallback">Diretta Match Live TV</string>
|
||||
<string name="broadcast_share_regia_subject">Link regia — %1$s</string>
|
||||
<string name="broadcast_error_regia_link">Errore link regia</string>
|
||||
<string name="broadcast_terminate_title">Terminare la diretta?</string>
|
||||
<string name="broadcast_terminate_message">Lo streaming verrà chiuso per tutti gli spettatori.</string>
|
||||
<string name="broadcast_terminate_confirm">TERMINA</string>
|
||||
<string name="broadcast_hide_controls_cd">Nascondi controlli</string>
|
||||
<string name="broadcast_show_controls_cd">Mostra controlli</string>
|
||||
<string name="broadcast_share_live_cd">Condividi diretta</string>
|
||||
<string name="broadcast_share_regia_cd">Condividi link regia</string>
|
||||
<string name="broadcast_next_period_cd">Periodo successivo</string>
|
||||
<string name="broadcast_resume_cd">Riprendi diretta</string>
|
||||
<string name="broadcast_pause_cd">Pausa diretta</string>
|
||||
<string name="broadcast_terminate_cd">Termina diretta</string>
|
||||
<string name="broadcast_team_home_label">CASA</string>
|
||||
<string name="broadcast_team_away_label">OSPITE</string>
|
||||
<string name="broadcast_scoreboard_connected">Tabellone OK</string>
|
||||
<string name="broadcast_scoreboard_offline">Tabellone offline</string>
|
||||
<string name="broadcast_period_label_timed">%1$d° tempo</string>
|
||||
<string name="broadcast_set_progress">Set %1$d · %2$d pt</string>
|
||||
<string name="broadcast_team_sets_count">%1$d set</string>
|
||||
<string name="broadcast_sets_won">Set vinti %1$d-%2$d</string>
|
||||
<string name="broadcast_side_home">casa</string>
|
||||
<string name="broadcast_side_away">ospite</string>
|
||||
<string name="broadcast_tooltip_plus_side">+%1$d %2$s</string>
|
||||
<string name="broadcast_tooltip_add_point">Aggiungi punto %1$s</string>
|
||||
<string name="broadcast_tooltip_remove_point">Togli punto %1$s</string>
|
||||
<string name="broadcast_share_chooser_title">Condividi</string>
|
||||
<string name="broadcast_close_set_button">CHIUDI SET</string>
|
||||
<string name="broadcast_points_target">%1$d pt</string>
|
||||
|
||||
<string name="score_set_won_title">Set concluso</string>
|
||||
<string name="score_set_won_message">%1$s vince il set %2$d-%3$d.\n\nChiudere il set e passare al successivo?</string>
|
||||
<string name="score_action_close_set">Chiudi set</string>
|
||||
<string name="score_action_continue_scoring">Continua a segnare</string>
|
||||
<string name="score_close_set_anyway_message">Il punteggio non soddisfa ancora le regole del torneo. Chiudere il set comunque?</string>
|
||||
<string name="score_action_close_anyway">Chiudi comunque</string>
|
||||
<string name="score_match_won_title">Partita terminata</string>
|
||||
<string name="score_match_won_message">%1$s vince la partita (%2$d-%3$d set).\n\nChiudere definitivamente la diretta?</string>
|
||||
<string name="score_action_close_live">Chiudi diretta</string>
|
||||
<string name="score_action_continue_live">Continua in onda</string>
|
||||
|
||||
<string name="sheet_choose_team">Scegli squadra</string>
|
||||
<string name="sheet_new_match_title">Nuova partita</string>
|
||||
<string name="sheet_new_match_lead">Programma in anticipo o avvia la configurazione diretta subito.</string>
|
||||
<string name="sheet_schedule_option">Programma partita</string>
|
||||
<string name="sheet_schedule_option_sub">Data, ora e avversario — visibile anche sul sito</string>
|
||||
<string name="sheet_quick_option">Avvia subito</string>
|
||||
<string name="sheet_quick_option_sub">Crea la partita e passa al wizard senza orario</string>
|
||||
<string name="sheet_schedule_title">Programma partita</string>
|
||||
<string name="sheet_schedule_lead">La diretta non parte ora: comparirà sul sito con data e ora. Avvierai lo streaming dall\'app quando sei in palestra.</string>
|
||||
<string name="sheet_opponent">Avversario</string>
|
||||
<string name="sheet_location_optional">Luogo (opzionale)</string>
|
||||
<string name="sheet_date_time">Data e ora</string>
|
||||
<string name="sheet_save_schedule">SALVA IN PROGRAMMA</string>
|
||||
<string name="sheet_choose_match">Scegli partita</string>
|
||||
<string name="sheet_choose_match_lead">Partite già programmate sul sito o in app.</string>
|
||||
<string name="sheet_section_scheduled">Programmate</string>
|
||||
<string name="sheet_section_unscheduled">Senza orario</string>
|
||||
<string name="sheet_badge_draft">BOZZA</string>
|
||||
<string name="sheet_badge_scheduled">PROGRAMMATA</string>
|
||||
<string name="sheet_badge_calendar">IN CALENDARIO</string>
|
||||
<string name="sheet_live_in_progress">Diretta in corso</string>
|
||||
<string name="sheet_status">Stato: %1$s</string>
|
||||
<string name="sheet_resume_camera">RIPRENDI CAMERA E TRASMETTI</string>
|
||||
<string name="sheet_continue_setup">CONTINUA CONFIGURAZIONE</string>
|
||||
<string name="sheet_configure_now_title">Configurare ora?</string>
|
||||
<string name="sheet_configure_now_body">Puoi preparare la trasmissione subito, oppure tornare quando sei in palestra.</string>
|
||||
<string name="sheet_configure">Configura</string>
|
||||
<string name="sheet_later">Più tardi</string>
|
||||
<string name="sheet_delete_match_title">Elimina partita</string>
|
||||
<string name="sheet_delete_match_body">Eliminare «%1$s vs %2$s»?
|
||||
|
||||
L\'operazione non si può annullare.</string>
|
||||
<string name="sheet_delete">Elimina</string>
|
||||
<string name="sheet_resume_banner">Riprendi diretta in corso</string>
|
||||
<string name="match_status_resume">RIPRENDI</string>
|
||||
<string name="match_status_live">IN CORSO</string>
|
||||
<string name="match_status_scheduled">PROGRAMMATA</string>
|
||||
<string name="match_status_start">AVVIA</string>
|
||||
<string name="matches_msg_load_error">Errore caricamento</string>
|
||||
<string name="matches_msg_resume_failed">Impossibile riprendere la diretta</string>
|
||||
<string name="matches_msg_create_failed">Impossibile creare la partita</string>
|
||||
<string name="matches_msg_scheduled_ok">Partita programmata — visibile sul sito</string>
|
||||
<string name="matches_msg_schedule_error">Errore creazione partita</string>
|
||||
<string name="matches_msg_deleted">Partita eliminata</string>
|
||||
<string name="matches_msg_delete_failed">Impossibile eliminare</string>
|
||||
<string name="login_email_placeholder">coach@team.com</string>
|
||||
<string name="action_delete">Elimina</string>
|
||||
<string name="wizard_color_hue">Tonalità</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user