clean code

This commit is contained in:
adrienmalin 2018-12-05 11:09:58 +01:00
parent d65944be2e
commit 5b41d35db3
8 changed files with 125 additions and 96 deletions

Binary file not shown.

View File

@ -1,25 +1,44 @@
package adrienmalin.pingpoints
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.view.View
import android.arch.lifecycle.ViewModelProviders
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.speech.RecognizerIntent
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.app.AppCompatDelegate
import android.text.method.LinkMovementMethod
import android.view.Menu
import android.view.MenuItem
import android.widget.*
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import java.util.*
import java.util.regex.Pattern
class MatchActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
class MatchActivity : AppCompatActivity() {
inner class WaitForTtsInit : TextToSpeech.OnInitListener {
override fun onInit(status: Int) {
ttsSpeak()
}
}
inner class WaitForTtsSpeak : UtteranceProgressListener() {
override fun onDone(id: String) {
launchStt()
}
override fun onStart(id: String) {}
override fun onError(id: String) {}
}
val REQ_CODE_SPEECH_INPUT = 1
val STT_RETRIES = 3
var matchModel: MatchModel? = null
var textScore: android.widget.TextView? = null
@ -29,6 +48,7 @@ class MatchActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
var tts: TextToSpeech? = null
var undo: MenuItem? = null
var redo: MenuItem? = null
var numSttCancelled:Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -56,17 +76,18 @@ class MatchActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
// Init or restore ViewModel
matchModel = ViewModelProviders.of(this).get(MatchModel::class.java)
matchModel?.let {
if (!it.matchStarted) {
matchModel?.apply {
if (!matchStarted) {
intent.apply {
it.startMatch(
startMatch(
getStringExtra("player1Name"),
getStringExtra("player2Name"),
getIntExtra("starterId", 0),
getBooleanExtra("enableTTS", false),
getBooleanExtra("enableSTT", false)
)
for (player in it.players) player.pattern = Pattern.compile(getString(R.string.pattern, player.name))
for (player in players)
player.pattern = Pattern.compile(this@MatchActivity.getString(R.string.pattern, player.name))
}
Snackbar.make(
findViewById(R.id.coordinatorLayout),
@ -74,18 +95,14 @@ class MatchActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
Snackbar.LENGTH_SHORT
).show()
}
if (it.ttsEnabled) {
tts = TextToSpeech(this, this)
if (it.sttEnabled) tts?.setOnUtteranceProgressListener(WaitForTTS(::launchStt))
if (ttsEnabled) {
tts = TextToSpeech(this@MatchActivity, WaitForTtsInit())
if (sttEnabled) tts?.setOnUtteranceProgressListener(WaitForTtsSpeak())
}
}
updateUI()
}
override fun onInit(status: Int) {
ttsSpeak()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.match_menu, menu)
undo = menu.findItem(R.id.action_undo)
@ -229,20 +246,20 @@ class MatchActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQ_CODE_SPEECH_INPUT -> {
matchModel?.let {
matchModel?.apply {
if (resultCode == RESULT_OK && data != null) {
var understood: Boolean = false
val result: String = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)[0]
for (player in it.players) {
for (player in players) {
if (player.pattern?.matcher(result)?.find() == true) {
understood = true
it.updateScore(player)
updateScore(player)
updateUI()
break
}
}
if (!understood) {
if (it.ttsEnabled) {
if (ttsEnabled) {
tts?.speak(
getString(R.string.not_understood),
TextToSpeech.QUEUE_FLUSH,
@ -258,6 +275,10 @@ class MatchActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
launchStt()
}
}
} else {
numSttCancelled++
if (numSttCancelled >= STT_RETRIES)
sttEnabled = false
}
}
}

View File

@ -34,12 +34,14 @@ class MatchModel : ViewModel() {
if ((players.sumBy { it.score } % 2 == 0) or (players.all { it.score >= 10 })) {
serviceSide = relaunchSide.also { relaunchSide = serviceSide }
}
saveState()
updateMatch()
}
fun updateMatch() {
val (minScore, maxScore) = players.map { it.score }.sorted()
matchFinished = (maxScore >= 11) and (maxScore - minScore >= 2)
matchPoint = (maxScore >= 10) and (maxScore - minScore >= 1)
saveState()
}
fun saveState() {
@ -71,5 +73,6 @@ class MatchModel : ViewModel() {
else -> 0
}
}
updateMatch()
}
}

View File

@ -1,7 +1,6 @@
package adrienmalin.pingpoints
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
@ -30,7 +29,6 @@ class StarterNameActivity : AppCompatActivity() {
var previousMatch: SharedPreferences? = null
var previousPlayers: Set<String> = emptySet()
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_starter_name)
@ -42,32 +40,36 @@ class StarterNameActivity : AppCompatActivity() {
starterRadioGroup = findViewById(R.id.starterRadioGroup)
enableTtsSwitch = findViewById(R.id.enableTtsSwitch)
enableSttSwitch = findViewById(R.id.enableSttSwitch)
// Check if function is available on switch checked or swapped
enableTtsSwitch?.setOnCheckedChangeListener { view, isChecked -> checkTTS() }
enableTtsSwitch?.setOnTouchListener { view, event -> checkTTS(); false}
enableSttSwitch?.setOnCheckedChangeListener { view, isChecked -> checkSTT() }
enableSttSwitch?.setOnTouchListener { view, event -> checkSTT(); false}
// Restore
// Restore previous data
previousMatch = getPreferences(Context.MODE_PRIVATE)
previousMatch?.let {
previousPlayers = it.getStringSet("previousPlayers", emptySet())
val adapter = ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, previousPlayers.toList())
previousMatch?.apply {
previousPlayers = getStringSet("previousPlayers", emptySet())
val adapter = ArrayAdapter<String>(
this@StarterNameActivity,
android.R.layout.simple_list_item_1,
previousPlayers.toList())
player1NameInput?.run {
setText(
it.getString("previousPlayer2", getString(R.string.player_1_default_name)),
getString("previousPlayer2", getString(R.string.player_1_default_name)),
TextView.BufferType.EDITABLE)
setAdapter(adapter)
}
player2NameInput?.run{
setText(
it.getString("previousPlayer1", getString(R.string.player_2_default_name)),
getString("previousPlayer1", getString(R.string.player_2_default_name)),
TextView.BufferType.EDITABLE)
setAdapter(adapter)
}
starterRadioGroup?.check(it.getInt("previousStarterId", R.id.radioPlayer1Starts))
enableTtsSwitch?.isChecked = it.getBoolean("enableTTS", false)
enableSttSwitch?.isChecked = it.getBoolean("enableSTT", false)
starterRadioGroup?.check(getInt("previousStarterId", R.id.radioPlayer1Starts))
enableTtsSwitch?.isChecked = getBoolean("enableTTS", false)
enableSttSwitch?.isChecked = getBoolean("enableSTT", false)
}
}
@ -78,15 +80,13 @@ class StarterNameActivity : AppCompatActivity() {
}
fun checkTTS(){
enableTtsSwitch?.let {
if (it.isChecked) {
Intent().run {
if (enableTtsSwitch?.isChecked == true) {
Intent().apply {
action = TextToSpeech.Engine.ACTION_CHECK_TTS_DATA
startActivityForResult(this, CHECK_TTS)
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
@ -99,7 +99,7 @@ class StarterNameActivity : AppCompatActivity() {
Snackbar.LENGTH_SHORT
).show()
enableTtsSwitch?.isChecked = false
Intent().run {
Intent().apply {
action = TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA
startActivity(this)
}
@ -110,35 +110,51 @@ class StarterNameActivity : AppCompatActivity() {
}
fun checkSTT(){
enableSttSwitch?.let {
if (it.isChecked) {
if (!SpeechRecognizer.isRecognitionAvailable(this)) {
enableSttSwitch?.apply {
if (isChecked) {
if (!SpeechRecognizer.isRecognitionAvailable(this@StarterNameActivity)) {
Snackbar.make(
findViewById(R.id.coordinatorLayout),
R.string.STT_unavailable,
Snackbar.LENGTH_SHORT
).show()
enableSttSwitch?.isChecked = false
isChecked = false
} else {
// Ask for record audio permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(
this@StarterNameActivity,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
AlertDialog.Builder(this)
.setTitle(R.string.STT)
.setMessage(R.string.explain_record_audio_request)
.setPositiveButton(R.string.OK) { dialog, id ->
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO), ASK_PERMISSIONS_RECORD_AUDIO)
if (ActivityCompat.shouldShowRequestPermissionRationale(
this@StarterNameActivity,
Manifest.permission.RECORD_AUDIO
)
) {
AlertDialog.Builder(this@StarterNameActivity).apply {
setTitle(R.string.STT)
setMessage(R.string.explain_record_audio_request)
setPositiveButton(R.string.OK) { dialog, id ->
ActivityCompat.requestPermissions(
this@StarterNameActivity,
arrayOf(Manifest.permission.RECORD_AUDIO),
ASK_PERMISSIONS_RECORD_AUDIO
)
}
.setNegativeButton(R.string.cancel) { dialog, id ->
enableSttSwitch?.isChecked = false
setNegativeButton(R.string.cancel) { dialog, id ->
isChecked = false
}
create()
show()
}
.create()
.show()
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO), ASK_PERMISSIONS_RECORD_AUDIO)
ActivityCompat.requestPermissions(
this@StarterNameActivity,
arrayOf(Manifest.permission.RECORD_AUDIO),
ASK_PERMISSIONS_RECORD_AUDIO
)
}
}
}

View File

@ -27,11 +27,11 @@ class VictoryActivity : AppCompatActivity() {
// Init victoryModel
victoryModel = ViewModelProviders.of(this).get(VictoryModel::class.java)
victoryModel?.let {
if (!it.matchFinished) {
it.matchFinished = true
it.winnerName = intent.getStringExtra("winnerName")
it.players = listOf(
victoryModel?.apply {
if (!matchFinished) {
matchFinished = true
winnerName = intent.getStringExtra("winnerName")
players = listOf(
Player(
intent.getStringExtra("player1Name"),
intent.getIntExtra("player1Score", 0)
@ -42,36 +42,36 @@ class VictoryActivity : AppCompatActivity() {
)
)
it.previousMatches = previousMatch.getString("previousMatches", "")
previousMatches = previousMatch.getString("previousMatches", "")
previousMatch.edit().apply {
putString(
"previousMatches",
getString(
R.string.result,
it.players[0].name,
it.players[0].score,
it.players[1].score,
it.players[1].name
) + it.previousMatches
players[0].name,
players[0].score,
players[1].score,
players[1].name
) + previousMatches
)
commit()
}
}
// UpdateUI
findViewById<TextView>(R.id.congrats).text = getString(R.string.congrats, it.winnerName)
findViewById<TextView>(R.id.player1NameTextView).text = it.players[0].name
findViewById<TextView>(R.id.congrats).text = getString(R.string.congrats, winnerName)
findViewById<TextView>(R.id.player1NameTextView).text = players[0].name
findViewById<TextView>(R.id.scoreTextView).text = getString(
R.string.score,
it.players[0].score,
it.players[1].score
players[0].score,
players[1].score
)
findViewById<TextView>(R.id.player2NameTextView).text = it.players[1].name
findViewById<TextView>(R.id.player2NameTextView).text = players[1].name
findViewById<GridView>(R.id.previousMatchesGrid).adapter = ArrayAdapter<String>(
this,
this@VictoryActivity,
R.layout.grid_item,
R.id.grid_item_text,
it.previousMatches.split("\t|\n".toRegex())
previousMatches.split("\t|\n".toRegex())
)
}
}
@ -83,7 +83,7 @@ class VictoryActivity : AppCompatActivity() {
}
fun share(view: View) {
victoryModel?.let {
victoryModel?.apply {
startActivity(
Intent().apply {
action = Intent.ACTION_SEND
@ -91,19 +91,19 @@ class VictoryActivity : AppCompatActivity() {
Intent.EXTRA_SUBJECT,
getString(
R.string.share_subject,
it.players[0].name,
it.players[1].name
players[0].name,
players[1].name
)
)
putExtra(
Intent.EXTRA_TEXT,
getString(
R.string.share_message,
it.players[0].name,
it.players[1].name,
it.winnerName,
it.players[0].score,
it.players[1].score
players[0].name,
players[1].name,
winnerName,
players[0].score,
players[1].score
)
)
type = "text/plain"

View File

@ -1,11 +0,0 @@
package adrienmalin.pingpoints
import android.speech.tts.UtteranceProgressListener
class WaitForTTS(val callback: () -> Unit) : UtteranceProgressListener() {
override fun onDone(id: String) {
callback()
}
override fun onStart(id: String) {}
override fun onError(id: String) {}
}

View File

@ -38,6 +38,6 @@ Vous pouvez à tout moment changer la permission dans les paramètres Android."
<string name="share_message">"%s contre %s:\n%s a gagné par %d à %d\nPing Points est disponible sur Google Play\n "</string>
<string name="match_point">Balle de match</string>
<string name="STT_hint">Dîtes : \"Point pour %s\"\nou \"Point pour %s\"</string>
<string name="pattern">point pour %s</string>
<string name="pattern">(?i:Point pour %s)</string>
<string name="not_understood">Pouvez-vous répéter ?</string>
</resources>

View File

@ -44,7 +44,7 @@
<string name="share_message">%s vs. %s:\n%s won by %d to %d\nGet Ping Points on Google Play</string>
<string name="match_point">Match point</string>
<string name="STT_hint">Say: \"Point for %s\"\nor \"Point for %s\"</string>
<string name="pattern">point for %s</string>
<string name="pattern">(?i:Point for %s)</string>
<string name="not_understood">Can you repeat?</string>
<string name="score" translatable="false">%d - %d</string>
</resources>