Skip to content

Commit 4b6f8ac

Browse files
committed
refactor,fix(data,ime,ui,res): enhance key sound theme management
- Add preference to enable/disable to use custom sound theme (package) - Utilize kaml library to parse sound theme configurations - Ship stuffs of parsing the configurations to SoundManager - Ship stuffs of playing the custom key effect to InputFeedbackManager
1 parent 231d992 commit 4b6f8ac

File tree

14 files changed

+211
-315
lines changed

14 files changed

+211
-315
lines changed

app/src/main/java/com/osfans/trime/data/AppPrefs.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ class AppPrefs(
145145

146146
const val SOUND_ENABLED = "keyboard__key_sound"
147147
const val SOUND_VOLUME = "keyboard__key_sound_volume"
148-
const val SOUND_PACKAGE = "keyboard__key_sound_package"
148+
const val CUSTOM_SOUND_ENABLED = "keyboard__custom_key_sound"
149+
const val CUSTOM_SOUND_PACKAGE = "keyboard__key_sound_package"
149150

150151
const val VIBRATION_ENABLED = "keyboard__key_vibration"
151152
const val VIBRATION_DURATION = "keyboard__key_vibration_duration"
@@ -224,9 +225,12 @@ class AppPrefs(
224225
var soundEnabled: Boolean = false
225226
get() = prefs.getPref(SOUND_ENABLED, false)
226227
private set
227-
var soundPackage: String
228-
get() = prefs.getPref(SOUND_PACKAGE, "")
229-
set(v) = prefs.setPref(SOUND_PACKAGE, v)
228+
var customSoundEnabled: Boolean
229+
get() = prefs.getPref(CUSTOM_SOUND_ENABLED, false)
230+
set(v) = prefs.setPref(CUSTOM_SOUND_ENABLED, v)
231+
var customSoundPackage: String
232+
get() = prefs.getPref(CUSTOM_SOUND_PACKAGE, "")
233+
set(v) = prefs.setPref(CUSTOM_SOUND_PACKAGE, v)
230234
var soundVolume: Int = 0
231235
get() = prefs.getPref(SOUND_VOLUME, 100)
232236
private set

app/src/main/java/com/osfans/trime/data/sound/SoundManager.kt

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.osfans.trime.data.sound
2+
3+
import android.view.KeyEvent
4+
import kotlinx.serialization.Serializable
5+
import kotlinx.serialization.Transient
6+
7+
@Serializable
8+
data class SoundTheme(
9+
@Transient var name: String? = null,
10+
val sound: List<String>,
11+
val folder: String,
12+
val melody: List<String>? = null,
13+
val keyset: List<Key>
14+
) {
15+
@Serializable
16+
data class Key(
17+
val min: String? = null,
18+
val max: String? = null,
19+
val keys: List<String>? = null,
20+
val inOrder: Boolean,
21+
val sounds: List<Int>
22+
) {
23+
val sysKeys = keys?.map(String::uppercase)?.map(KeyEvent::keyCodeFromString)
24+
25+
fun soundId(keycode: Int): Int {
26+
if (sounds.isEmpty()) return -1
27+
if (sysKeys.isNullOrEmpty()) {
28+
val min = KeyEvent.keyCodeFromString(min?.uppercase() ?: "UNKNOWN")
29+
val max = KeyEvent.keyCodeFromString(max?.uppercase() ?: "UNKNOWN")
30+
if (keycode in min..max) {
31+
return sounds[if (inOrder) (keycode - min) % sounds.size else sounds.indices.random()]
32+
}
33+
} else {
34+
val sysKey = sysKeys.indexOf(keycode)
35+
if (sysKey > -1) {
36+
return sounds[if (inOrder) sysKey % sounds.size else sounds.indices.random()]
37+
}
38+
}
39+
return -1
40+
}
41+
}
42+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.osfans.trime.data.sound
2+
3+
import com.charleskorn.kaml.Yaml
4+
import com.charleskorn.kaml.YamlConfiguration
5+
import com.osfans.trime.data.AppPrefs
6+
import com.osfans.trime.data.DataManager
7+
import timber.log.Timber
8+
import java.io.File
9+
10+
object SoundThemeManager {
11+
12+
val userDir = File(DataManager.userDataDir, "sound")
13+
14+
private val yaml = Yaml(
15+
configuration = YamlConfiguration(
16+
strictMode = false
17+
)
18+
)
19+
20+
private fun listSounds(): MutableList<SoundTheme> {
21+
val files = userDir.listFiles { f -> f.name.endsWith("sound.yaml") }
22+
return files
23+
?.mapNotNull decode@{ f ->
24+
val theme = runCatching {
25+
yaml.decodeFromString(SoundTheme.serializer(), f.readText()).also {
26+
it.name = f.name.substringBefore('.')
27+
}
28+
}.getOrElse { e ->
29+
Timber.w("Failed to decode sound theme file ${f.absolutePath}: ${e.message}")
30+
return@decode null
31+
}
32+
return@decode theme
33+
}
34+
?.toMutableList() ?: mutableListOf()
35+
}
36+
37+
private fun getSound(name: String) = userSounds.find { it.name == name }
38+
39+
val userSounds: MutableList<SoundTheme> = listSounds()
40+
41+
@JvmStatic
42+
fun switchSound(name: String) {
43+
if (getSound(name) == null) {
44+
Timber.w("Unknown sound package name: $name")
45+
return
46+
}
47+
AppPrefs.defaultInstance().keyboard.customSoundPackage = name
48+
currentSoundTheme = getSound(name)!!
49+
}
50+
51+
fun init() {
52+
currentSoundTheme = getSound(AppPrefs.defaultInstance().keyboard.customSoundPackage) ?: return
53+
}
54+
55+
private lateinit var currentSoundTheme: SoundTheme
56+
57+
fun getAllSoundThemes(): List<SoundTheme> = userSounds
58+
59+
fun getActiveSoundTheme() = runCatching { currentSoundTheme }
60+
61+
fun getActiveSoundFilePaths() = runCatching {
62+
currentSoundTheme.let { t -> t.sound.map { "${userDir.path}/${t.folder}/$it" } }
63+
}
64+
}

app/src/main/java/com/osfans/trime/data/theme/Config.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import com.osfans.trime.core.Rime;
2828
import com.osfans.trime.data.AppPrefs;
2929
import com.osfans.trime.data.DataManager;
30-
import com.osfans.trime.data.sound.SoundManager;
30+
import com.osfans.trime.data.sound.SoundThemeManager;
3131
import com.osfans.trime.ime.keyboard.Key;
3232
import com.osfans.trime.util.CollectionUtils;
3333
import com.osfans.trime.util.ColorUtils;
@@ -80,7 +80,7 @@ public Config() {
8080
init();
8181

8282
Timber.d("Setting sound from color ...");
83-
SoundManager.switchSound(colors.getString("sound"));
83+
SoundThemeManager.switchSound(colors.getString("sound"));
8484

8585
Timber.d("Initialization finished");
8686
}

app/src/main/java/com/osfans/trime/ime/core/Trime.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
import com.osfans.trime.core.Rime;
5959
import com.osfans.trime.data.AppPrefs;
6060
import com.osfans.trime.data.db.DraftHelper;
61-
import com.osfans.trime.data.sound.SoundManager;
61+
import com.osfans.trime.data.sound.SoundThemeManager;
6262
import com.osfans.trime.data.theme.Config;
6363
import com.osfans.trime.databinding.CompositionRootBinding;
6464
import com.osfans.trime.databinding.InputRootBinding;
@@ -72,7 +72,6 @@
7272
import com.osfans.trime.ime.keyboard.Keyboard;
7373
import com.osfans.trime.ime.keyboard.KeyboardSwitcher;
7474
import com.osfans.trime.ime.keyboard.KeyboardView;
75-
import com.osfans.trime.ime.keyboard.Sound;
7675
import com.osfans.trime.ime.lifecycle.LifecycleInputMethodService;
7776
import com.osfans.trime.ime.symbol.LiquidKeyboard;
7877
import com.osfans.trime.ime.symbol.TabManager;
@@ -555,7 +554,7 @@ private void reset() {
555554
inputRootBinding.main.mainInput.setVisibility(View.VISIBLE);
556555
loadConfig();
557556
getImeConfig().initCurrentColors();
558-
SoundManager.switchSound(getImeConfig().colors.getString("sound"));
557+
SoundThemeManager.switchSound(getImeConfig().colors.getString("sound"));
559558
KeyboardSwitcher.newOrReset();
560559
resetCandidate();
561560
hideCompositionView();
@@ -576,7 +575,7 @@ public void initKeyboardDarkMode(boolean darkMode) {
576575
if (getImeConfig().hasDarkLight()) {
577576
loadConfig();
578577
getImeConfig().initCurrentColors(darkMode);
579-
SoundManager.switchSound(getImeConfig().colors.getString("sound"));
578+
SoundThemeManager.switchSound(getImeConfig().colors.getString("sound"));
580579
KeyboardSwitcher.newOrReset();
581580
resetCandidate();
582581
hideCompositionView();
@@ -752,7 +751,8 @@ public void onStartInputView(EditorInfo attribute, boolean restarting) {
752751
Timber.i("auto dark off");
753752
}
754753

755-
Sound.resetProgress();
754+
inputFeedbackManager.resumeSoundPool();
755+
inputFeedbackManager.resetPlayProgress();
756756
for (EventListener listener : eventListeners) {
757757
if (listener != null) listener.onStartInputView(activeEditorInstance, restarting);
758758
}
@@ -839,6 +839,7 @@ public void onFinishInputView(boolean finishingInput) {
839839
// Dismiss any pop-ups when the input-view is being finished and hidden.
840840
mainKeyboardView.closing();
841841
performEscape();
842+
inputFeedbackManager.releaseSoundPool();
842843
try {
843844
hideCompositionView();
844845
} catch (Exception e) {

0 commit comments

Comments
 (0)